Home | History | Annotate | Download | only in doclava
      1 /*
      2  * Copyright (C) 2010 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.doclava;
     18 
     19 import com.google.clearsilver.jsilver.data.Data;
     20 
     21 import java.util.ArrayList;
     22 import java.util.List;
     23 
     24 public class NavTree {
     25 
     26   public static void writeNavTree(String dir) {
     27     List<Node> children = new ArrayList<Node>();
     28     for (PackageInfo pkg : Doclava.choosePackages()) {
     29       children.add(makePackageNode(pkg));
     30     }
     31     Node node = new Node("Reference", dir + "packages.html", children, null);
     32 
     33     StringBuilder buf = new StringBuilder();
     34     if (false) {
     35       // if you want a root node
     36       buf.append("[");
     37       node.render(buf);
     38       buf.append("]");
     39     } else {
     40       // if you don't want a root node
     41       node.renderChildren(buf);
     42     }
     43 
     44     Data data = Doclava.makeHDF();
     45     data.setValue("reference_tree", buf.toString());
     46     ClearPage.write(data, "navtree_data.cs", "navtree_data.js");
     47   }
     48 
     49   private static Node makePackageNode(PackageInfo pkg) {
     50     List<Node> children = new ArrayList<Node>();
     51 
     52     addClassNodes(children, "Interfaces", pkg.interfaces());
     53     addClassNodes(children, "Classes", pkg.ordinaryClasses());
     54     addClassNodes(children, "Enums", pkg.enums());
     55     addClassNodes(children, "Exceptions", pkg.exceptions());
     56     addClassNodes(children, "Errors", pkg.errors());
     57 
     58     return new Node(pkg.name(), pkg.htmlPage(), children, pkg.getSince());
     59   }
     60 
     61   private static void addClassNodes(List<Node> parent, String label, ClassInfo[] classes) {
     62     List<Node> children = new ArrayList<Node>();
     63 
     64     for (ClassInfo cl : classes) {
     65       if (cl.checkLevel()) {
     66         children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince()));
     67       }
     68     }
     69 
     70     if (children.size() > 0) {
     71       parent.add(new Node(label, null, children, null));
     72     }
     73   }
     74 
     75   private static class Node {
     76     private String mLabel;
     77     private String mLink;
     78     List<Node> mChildren;
     79     private String mSince;
     80 
     81     Node(String label, String link, List<Node> children, String since) {
     82       mLabel = label;
     83       mLink = link;
     84       mChildren = children;
     85       mSince = since;
     86     }
     87 
     88     static void renderString(StringBuilder buf, String s) {
     89       if (s == null) {
     90         buf.append("null");
     91       } else {
     92         buf.append('"');
     93         final int N = s.length();
     94         for (int i = 0; i < N; i++) {
     95           char c = s.charAt(i);
     96           if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
     97             buf.append(c);
     98           } else {
     99             buf.append("\\u");
    100             for (int j = 0; i < 4; i++) {
    101               char x = (char) (c & 0x000f);
    102               if (x > 10) {
    103                 x = (char) (x - 10 + 'a');
    104               } else {
    105                 x = (char) (x + '0');
    106               }
    107               buf.append(x);
    108               c >>= 4;
    109             }
    110           }
    111         }
    112         buf.append('"');
    113       }
    114     }
    115 
    116     void renderChildren(StringBuilder buf) {
    117       List<Node> list = mChildren;
    118       if (list == null || list.size() == 0) {
    119         // We output null for no children. That way empty lists here can just
    120         // be a byproduct of how we generate the lists.
    121         buf.append("null");
    122       } else {
    123         buf.append("[ ");
    124         final int N = list.size();
    125         for (int i = 0; i < N; i++) {
    126           list.get(i).render(buf);
    127           if (i != N - 1) {
    128             buf.append(", ");
    129           }
    130         }
    131         buf.append(" ]\n");
    132       }
    133     }
    134 
    135     void render(StringBuilder buf) {
    136       buf.append("[ ");
    137       renderString(buf, mLabel);
    138       buf.append(", ");
    139       renderString(buf, mLink);
    140       buf.append(", ");
    141       renderChildren(buf);
    142       buf.append(", ");
    143       renderString(buf, mSince);
    144       buf.append(" ]");
    145     }
    146   }
    147 }
    148