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.JSilver;
20920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.data.Data;
21920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.resourceloader.ClassResourceLoader;
22920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.resourceloader.CompositeResourceLoader;
23920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.resourceloader.FileSystemResourceLoader;
24920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.resourceloader.ResourceLoader;
25920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
26920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.sun.javadoc.*;
27920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
28920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.*;
29920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.jar.JarFile;
3071bf8d2ae787c28691910bb228a5d9efca9b153dScott Mainimport java.util.regex.Matcher;
31920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.io.*;
32920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.lang.reflect.Proxy;
33920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.lang.reflect.Array;
34920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.lang.reflect.InvocationHandler;
35920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.lang.reflect.InvocationTargetException;
36920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.lang.reflect.Method;
37920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.net.MalformedURLException;
38920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.net.URL;
39920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
40920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpublic class Doclava {
41920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final String SDK_CONSTANT_ANNOTATION = "android.annotation.SdkConstant";
42920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final String SDK_CONSTANT_TYPE_ACTIVITY_ACTION =
43920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      "android.annotation.SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION";
44920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final String SDK_CONSTANT_TYPE_BROADCAST_ACTION =
45920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      "android.annotation.SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION";
46920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final String SDK_CONSTANT_TYPE_SERVICE_ACTION =
47920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      "android.annotation.SdkConstant.SdkConstantType.SERVICE_INTENT_ACTION";
48920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final String SDK_CONSTANT_TYPE_CATEGORY =
49920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      "android.annotation.SdkConstant.SdkConstantType.INTENT_CATEGORY";
50920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final String SDK_CONSTANT_TYPE_FEATURE =
51920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      "android.annotation.SdkConstant.SdkConstantType.FEATURE";
52920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final String SDK_WIDGET_ANNOTATION = "android.annotation.Widget";
53920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final String SDK_LAYOUT_ANNOTATION = "android.annotation.Layout";
54920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
55920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final int TYPE_NONE = 0;
56920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final int TYPE_WIDGET = 1;
57920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final int TYPE_LAYOUT = 2;
58920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final int TYPE_LAYOUT_PARAM = 3;
59920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
60920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static final int SHOW_PUBLIC = 0x00000001;
61920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static final int SHOW_PROTECTED = 0x00000003;
62920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static final int SHOW_PACKAGE = 0x00000007;
63920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static final int SHOW_PRIVATE = 0x0000000f;
64920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static final int SHOW_HIDDEN = 0x0000001f;
65920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
66920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static int showLevel = SHOW_PROTECTED;
67920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
68815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty  public static final boolean SORT_BY_NAV_GROUPS = true;
69c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  /* Debug output for PageMetadata, format urls from site root */
70c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  public static boolean META_DBG=false;
71815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty
729b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static String outputPathBase = "/";
739b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static ArrayList<String> inputPathHtmlDirs = new ArrayList<String>();
749b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static ArrayList<String> inputPathHtmlDir2 = new ArrayList<String>();
759b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static String outputPathHtmlDirs;
769b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static String outputPathHtmlDir2;
779b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static final String devsiteRoot = "en/";
789b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static String javadocDir = "reference/";
79920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static String htmlExtension;
80920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
81920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static RootDoc root;
82920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static ArrayList<String[]> mHDFData = new ArrayList<String[]>();
8342303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty  public static List<PageMetadata.Node> sTaglist = new ArrayList<PageMetadata.Node>();
845ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  public static ArrayList<SampleCode> sampleCodes = new ArrayList<SampleCode>();
85815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty  public static ArrayList<SampleCode> sampleCodeGroups = new ArrayList<SampleCode>();
867537229470687560714401104558abdf82f81441Dirk Dougherty  public static Data samplesNavTree;
87920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static Map<Character, String> escapeChars = new HashMap<Character, String>();
88920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static String title = "";
89920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static SinceTagger sinceTagger = new SinceTagger();
907a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato  public static HashSet<String> knownTags = new HashSet<String>();
91920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static FederationTagger federationTagger = new FederationTagger();
929b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static Set<String> showAnnotations = new HashSet<String>();
93cbc60decb8169f18422c25ae8a384e5d91cdfe74Alex Klyubin  public static Set<String> hiddenPackages = new HashSet<String>();
949b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static boolean includeDefaultAssets = true;
959ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson  private static boolean generateDocs = true;
969ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson  private static boolean parseComments = false;
9718b25554072c36d4d9652523ec15e0c5306101ceChirag Shah  private static String yamlNavFile = null;
98b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson  public static boolean documentAnnotations = false;
99b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson  public static String documentAnnotationsPath = null;
100b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson  public static Map<String, String> annotationDocumentationMap = null;
1013c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main
102920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static JSilver jSilver = null;
103920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1045ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly  private static boolean gmsRef = false;
1055ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly  private static boolean gcmRef = false;
1061b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  private static boolean samplesRef = false;
10788c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly  private static boolean sac = false;
1085ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly
109920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static boolean checkLevel(int level) {
110920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (showLevel & level) == level;
111920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1123c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main
113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1149ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson   * Returns true if we should parse javadoc comments,
1159ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson   * reporting errors in the process.
116920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1179ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson  public static boolean parseComments() {
1189ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson    return generateDocs || parseComments;
119920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
120920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
121920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static boolean checkLevel(boolean pub, boolean prot, boolean pkgp, boolean priv,
122920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      boolean hidden) {
123920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (hidden && !checkLevel(SHOW_HIDDEN)) {
124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return false;
125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (pub && checkLevel(SHOW_PUBLIC)) {
127920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return true;
128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (prot && checkLevel(SHOW_PROTECTED)) {
130920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return true;
131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (pkgp && checkLevel(SHOW_PACKAGE)) {
133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return true;
134920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (priv && checkLevel(SHOW_PRIVATE)) {
136920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return true;
137920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
138920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return false;
139920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
140920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void main(String[] args) {
142920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    com.sun.tools.javadoc.Main.execute(args);
143920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
144920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
145920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static boolean start(RootDoc r) {
146f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein    long startTime = System.nanoTime();
147920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String keepListFile = null;
148970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton    String proguardFile = null;
149920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String proofreadFile = null;
150920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String todoFile = null;
151920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String sdkValuePath = null;
152920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String stubsDir = null;
15341d8656cf17e04b25a058d0874e401654ea547b4Dirk Dougherty    // Create the dependency graph for the stubs  directory
154920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    boolean offlineMode = false;
155920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String apiFile = null;
1565118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu    String removedApiFile = null;
157920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String debugStubsFile = "";
158920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    HashSet<String> stubPackages = null;
1597a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    ArrayList<String> knownTagsFiles = new ArrayList<String>();
160920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
161920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    root = r;
162920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
163920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String[][] options = r.options();
164920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String[] a : options) {
165920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (a[0].equals("-d")) {
1669b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        outputPathBase = outputPathHtmlDirs = ClearPage.outputDir = a[1];
167920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-templatedir")) {
168920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ClearPage.addTemplateDir(a[1]);
169920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-hdf")) {
170920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        mHDFData.add(new String[] {a[1], a[2]});
1717a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato      } else if (a[0].equals("-knowntags")) {
1727a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato        knownTagsFiles.add(a[1]);
173920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-toroot")) {
174920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ClearPage.toroot = a[1];
175920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-samplecode")) {
176920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        sampleCodes.add(new SampleCode(a[1], a[2], a[3]));
177815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      } else if (a[0].equals("-samplegroup")) {
178815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty        sampleCodeGroups.add(new SampleCode(null, null, a[1]));
1795ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty      } else if (a[0].equals("-samplesdir")) {
1805ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty        getSampleProjects(new File(a[1]));
1819b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      //the destination output path for main htmldir
182920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-htmldir")) {
1839b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        inputPathHtmlDirs.add(a[1]);
1849b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        ClearPage.htmlDirs = inputPathHtmlDirs;
1859b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      //the destination output path for additional htmldir
1869b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      } else if (a[0].equals("-htmldir2")) {
1879b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty          if (a[2].equals("default")) {
1889b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty          inputPathHtmlDirs.add(a[1]);
1899b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        } else {
1909b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty          inputPathHtmlDir2.add(a[1]);
1919b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty          outputPathHtmlDir2 = a[2];
1929b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        }
193920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-title")) {
194920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        Doclava.title = a[1];
195920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-werror")) {
196920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        Errors.setWarningsAreErrors(true);
197920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-error") || a[0].equals("-warning") || a[0].equals("-hide")) {
198920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        try {
199920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          int level = -1;
200920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          if (a[0].equals("-error")) {
201920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            level = Errors.ERROR;
202920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          } else if (a[0].equals("-warning")) {
203920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            level = Errors.WARNING;
204920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          } else if (a[0].equals("-hide")) {
205920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            level = Errors.HIDDEN;
206920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
207920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Errors.setErrorLevel(Integer.parseInt(a[1]), level);
208920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        } catch (NumberFormatException e) {
209920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          // already printed below
210920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return false;
211920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
212920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-keeplist")) {
213920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        keepListFile = a[1];
2149b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      } else if (a[0].equals("-showAnnotation")) {
2159b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        showAnnotations.add(a[1]);
216cbc60decb8169f18422c25ae8a384e5d91cdfe74Alex Klyubin      } else if (a[0].equals("-hidePackage")) {
217cbc60decb8169f18422c25ae8a384e5d91cdfe74Alex Klyubin        hiddenPackages.add(a[1]);
218970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton      } else if (a[0].equals("-proguard")) {
2195ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly        proguardFile = a[1];
220920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-proofread")) {
221920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        proofreadFile = a[1];
222920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-todo")) {
223920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        todoFile = a[1];
224920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-public")) {
225920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        showLevel = SHOW_PUBLIC;
226920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-protected")) {
227920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        showLevel = SHOW_PROTECTED;
228920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-package")) {
229920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        showLevel = SHOW_PACKAGE;
230920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-private")) {
231920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        showLevel = SHOW_PRIVATE;
232920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-hidden")) {
233920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        showLevel = SHOW_HIDDEN;
234920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-stubs")) {
235920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        stubsDir = a[1];
236920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-stubpackages")) {
237920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        stubPackages = new HashSet<String>();
238920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        for (String pkg : a[1].split(":")) {
239920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          stubPackages.add(pkg);
240920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
241920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-sdkvalues")) {
242920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        sdkValuePath = a[1];
243040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      } else if (a[0].equals("-api")) {
244920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        apiFile = a[1];
2455118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      } else if (a[0].equals("-removedApi")) {
2465118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu        removedApiFile = a[1];
2475118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      }
2485118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      else if (a[0].equals("-nodocs")) {
2499ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson        generateDocs = false;
250e65daec66ebdf02baa00c0ee403321fa304f7ad5Dirk Dougherty      } else if (a[0].equals("-nodefaultassets")) {
251e65daec66ebdf02baa00c0ee403321fa304f7ad5Dirk Dougherty        includeDefaultAssets = false;
2529ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson      } else if (a[0].equals("-parsecomments")) {
2539ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson        parseComments = true;
254920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-since")) {
255920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        sinceTagger.addVersion(a[1], a[2]);
256920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-offlinemode")) {
257920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        offlineMode = true;
258c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty      } else if (a[0].equals("-metadataDebug")) {
259c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty        META_DBG = true;
260920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-federate")) {
261920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        try {
262920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          String name = a[1];
263920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          URL federationURL = new URL(a[2]);
2641e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton          federationTagger.addSiteUrl(name, federationURL);
265920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        } catch (MalformedURLException e) {
266920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          System.err.println("Could not parse URL for federation: " + a[1]);
267920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return false;
268920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
2691e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton      } else if (a[0].equals("-federationapi")) {
2701e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton        String name = a[1];
2711e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton        String file = a[2];
2721e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton        federationTagger.addSiteApi(name, file);
27318b25554072c36d4d9652523ec15e0c5306101ceChirag Shah      } else if (a[0].equals("-yaml")) {
27418b25554072c36d4d9652523ec15e0c5306101ceChirag Shah        yamlNavFile = a[1];
2759b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      } else if (a[0].equals("-devsite")) {
2769b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        // Don't copy the doclava assets to devsite output (ie use proj assets only)
2779b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        includeDefaultAssets = false;
2789b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        outputPathHtmlDirs = outputPathHtmlDirs + "/" + devsiteRoot;
279b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson      } else if (a[0].equals("-documentannotations")) {
280b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson        documentAnnotations = true;
281b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson        documentAnnotationsPath = a[1];
282920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
283920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
284920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
2857a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    if (!readKnownTagsFiles(knownTags, knownTagsFiles)) {
2867a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato      return false;
2877a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    }
288920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
289920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Set up the data structures
290920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Converter.makeInfo(r);
291920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
2929ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson    if (generateDocs) {
293920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClearPage.addBundledTemplateDir("assets/customizations");
294920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClearPage.addBundledTemplateDir("assets/templates");
295920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
296920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      List<ResourceLoader> resourceLoaders = new ArrayList<ResourceLoader>();
297920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      List<String> templates = ClearPage.getTemplateDirs();
298920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (String tmpl : templates) {
299920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        resourceLoaders.add(new FileSystemResourceLoader(tmpl));
300920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
301920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
302920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      templates = ClearPage.getBundledTemplateDirs();
303920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (String tmpl : templates) {
304f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein          // TODO - remove commented line - it's here for debugging purposes
305f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein        //  resourceLoaders.add(new FileSystemResourceLoader("/Volumes/Android/master/external/doclava/res/" + tmpl));
306920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        resourceLoaders.add(new ClassResourceLoader(Doclava.class, '/'+tmpl));
307920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
308920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
309920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ResourceLoader compositeResourceLoader = new CompositeResourceLoader(resourceLoaders);
310920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      jSilver = new JSilver(compositeResourceLoader);
311920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
312920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (!Doclava.readTemplateSettings()) {
313920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return false;
314920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
315920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
316f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein      //startTime = System.nanoTime();
317920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
318920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Apply @since tags from the XML file
319920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sinceTagger.tagAll(Converter.rootClasses());
3203c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main
321920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Apply details of federated documentation
322920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      federationTagger.tagAll(Converter.rootClasses());
323920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
324920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Files for proofreading
325920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (proofreadFile != null) {
326920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        Proofread.initProofread(proofreadFile);
327920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
328920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (todoFile != null) {
329920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        TodoFile.writeTodoFile(todoFile);
330920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
331920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
332c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  if (samplesRef) {
3337537229470687560714401104558abdf82f81441Dirk Dougherty        // always write samples without offlineMode behaviors
334c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  writeSamples(false, sampleCodes, SORT_BY_NAV_GROUPS);
335c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  }
3367537229470687560714401104558abdf82f81441Dirk Dougherty
3379b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      // HTML2 Pages -- Generate Pages from optional secondary dir
3389b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      if (!inputPathHtmlDir2.isEmpty()) {
3399b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        if (!outputPathHtmlDir2.isEmpty()) {
3409b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty          ClearPage.outputDir = outputPathBase + "/" + outputPathHtmlDir2;
3419b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        }
3429b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        ClearPage.htmlDirs = inputPathHtmlDir2;
3439b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        writeHTMLPages();
3449b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        ClearPage.htmlDirs = inputPathHtmlDirs;
3459b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      }
3469b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty
347920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // HTML Pages
3484bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      if (!ClearPage.htmlDirs.isEmpty()) {
3499b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        ClearPage.htmlDirs = inputPathHtmlDirs;
3509b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        ClearPage.outputDir = outputPathHtmlDirs;
351920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeHTMLPages();
352920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
353920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
354920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      writeAssets();
3555118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu
356920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Navigation tree
3571b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      String refPrefix = new String();
3585ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      if(gmsRef){
3595ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly        refPrefix = "gms-";
3605ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      } else if(gcmRef){
3615ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly        refPrefix = "gcm-";
3625ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      }
3635ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      NavTree.writeNavTree(javadocDir, refPrefix);
364920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
36518b25554072c36d4d9652523ec15e0c5306101ceChirag Shah      // Write yaml tree.
36618b25554072c36d4d9652523ec15e0c5306101ceChirag Shah      if (yamlNavFile != null){
36718b25554072c36d4d9652523ec15e0c5306101ceChirag Shah        NavTree.writeYamlTree(javadocDir, yamlNavFile);
36818b25554072c36d4d9652523ec15e0c5306101ceChirag Shah      }
36918b25554072c36d4d9652523ec15e0c5306101ceChirag Shah
370920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Packages Pages
3715ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      writePackages(javadocDir + refPrefix + "packages" + htmlExtension);
372920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
373920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Classes
374c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  writeClassLists();
375c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  writeClasses();
376c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  writeHierarchy();
377920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // writeKeywords();
378920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
379920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Lists for JavaScript
380c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  writeLists();
381920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (keepListFile != null) {
382920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeKeepList(keepListFile);
383920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
384920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
385920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Index page
386c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  writeIndex();
387920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
388c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  Proofread.finishProofread(proofreadFile);
389920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
390c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  if (sdkValuePath != null) {
391c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty    writeSdkValues(sdkValuePath);
392c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty  }
39342303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty      // Write metadata for all processed files to jd_lists_unified.js in out dir
39442303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty      if (!sTaglist.isEmpty()) {
39542303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty        PageMetadata.WriteList(sTaglist);
39642303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty      }
397920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
398920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
399920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Stubs
4005118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu    if (stubsDir != null || apiFile != null || proguardFile != null || removedApiFile != null) {
4015118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      Stubs.writeStubsAndApi(stubsDir, apiFile, proguardFile, removedApiFile, stubPackages);
402920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
403920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
404920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Errors.printErrors();
4053c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main
406f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein    long time = System.nanoTime() - startTime;
407f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein    System.out.println("DroidDoc took " + (time / 1000000000) + " sec. to write docs to "
4089b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        + outputPathBase );
409f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein
410920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return !Errors.hadError;
411920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
412920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
413920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeIndex() {
414920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makeHDF();
415920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "index.cs", javadocDir + "index" + htmlExtension);
416920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
417920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
418920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static boolean readTemplateSettings() {
419920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makeHDF();
420920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
421920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // The .html extension is hard-coded in several .cs files,
422920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // and so you cannot currently set it as a property.
423920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    htmlExtension = ".html";
424920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // htmlExtension = data.getValue("template.extension", ".html");
425920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i = 0;
426920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    while (true) {
427920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String k = data.getValue("template.escape." + i + ".key", "");
428920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String v = data.getValue("template.escape." + i + ".value", "");
429920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if ("".equals(k)) {
430920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        break;
431920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
432920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (k.length() != 1) {
433920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        System.err.println("template.escape." + i + ".key must have a length of 1: " + k);
434920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return false;
435920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
436920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      escapeChars.put(k.charAt(0), v);
437920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      i++;
438920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
439920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return true;
440920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
441920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
4427a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    private static boolean readKnownTagsFiles(HashSet<String> knownTags,
4437a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato            ArrayList<String> knownTagsFiles) {
4447a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato        for (String fn: knownTagsFiles) {
4457a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato           BufferedReader in = null;
4467a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato           try {
4477a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               in = new BufferedReader(new FileReader(fn));
4487a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               int lineno = 0;
4497a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               boolean fail = false;
4507a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               while (true) {
4517a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   lineno++;
4527a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   String line = in.readLine();
4537a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   if (line == null) {
4547a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       break;
4557a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   }
4567a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   line = line.trim();
4577a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   if (line.length() == 0) {
4587a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       continue;
4597a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   } else if (line.charAt(0) == '#') {
4607a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       continue;
4617a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   }
4627a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   String[] words = line.split("\\s+", 2);
4637a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   if (words.length == 2) {
4647a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       if (words[1].charAt(0) != '#') {
4657a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                           System.err.println(fn + ":" + lineno
4667a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                                   + ": Only one tag allowed per line: " + line);
4677a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                           fail = true;
4687a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                           continue;
4697a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       }
4707a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   }
4717a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   knownTags.add(words[0]);
4727a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               }
4737a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               if (fail) {
4747a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   return false;
4757a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               }
4767a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato           } catch (IOException ex) {
4777a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               System.err.println("Error reading file: " + fn + " (" + ex.getMessage() + ")");
4787a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               return false;
4797a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato           } finally {
4807a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               if (in != null) {
4817a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   try {
4827a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       in.close();
4837a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   } catch (IOException e) {
4847a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   }
4857a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               }
4867a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato           }
4877a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato        }
4887a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato        return true;
4897a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    }
4907a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato
491920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static String escape(String s) {
492920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (escapeChars.size() == 0) {
493920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return s;
494920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
495920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    StringBuffer b = null;
496920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int begin = 0;
497920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    final int N = s.length();
498920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < N; i++) {
499920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      char c = s.charAt(i);
500920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String mapped = escapeChars.get(c);
501920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (mapped != null) {
502920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (b == null) {
503920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          b = new StringBuffer(s.length() + mapped.length());
504920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
505920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (begin != i) {
506920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          b.append(s.substring(begin, i));
507920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
508920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        b.append(mapped);
509920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        begin = i + 1;
510920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
511920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
512920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (b != null) {
513920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (begin != N) {
514920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        b.append(s.substring(begin, N));
515920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
516920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return b.toString();
517920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
518920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return s;
519920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
520920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
521920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void setPageTitle(Data data, String title) {
522920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String s = title;
523920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (Doclava.title.length() > 0) {
524920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      s += " - " + Doclava.title;
525920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
526920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue("page.title", s);
527920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
528920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
529920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
530920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static LanguageVersion languageVersion() {
531920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return LanguageVersion.JAVA_1_5;
532920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
533920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
534920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
535920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static int optionLength(String option) {
536920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-d")) {
537920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
538920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
539920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-templatedir")) {
540920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
541920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
542920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-hdf")) {
543920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 3;
544920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
5457a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    if (option.equals("-knowntags")) {
5467a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato      return 2;
5477a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    }
548920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-toroot")) {
549920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
550920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
551920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-samplecode")) {
5521b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      samplesRef = true;
553920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 4;
554920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
555815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    if (option.equals("-samplegroup")) {
556815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      return 2;
557815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    }
5585ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty    if (option.equals("-samplesdir")) {
5595ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty      samplesRef = true;
5605ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty      return 2;
5615ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty    }
5621b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    if (option.equals("-devsite")) {
5631b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      return 1;
5641b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
565920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-htmldir")) {
566920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
567920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
5689b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    if (option.equals("-htmldir2")) {
5699b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      return 3;
5709b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    }
571920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-title")) {
572920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
573920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
574920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-werror")) {
575920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
576920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
577920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-hide")) {
578920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
579920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
580920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-warning")) {
581920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
582920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
583920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-error")) {
584920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
585920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
586920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-keeplist")) {
587920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
588920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
5899b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    if (option.equals("-showAnnotation")) {
5909b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      return 2;
5919b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    }
592cbc60decb8169f18422c25ae8a384e5d91cdfe74Alex Klyubin    if (option.equals("-hidePackage")) {
593cbc60decb8169f18422c25ae8a384e5d91cdfe74Alex Klyubin      return 2;
594cbc60decb8169f18422c25ae8a384e5d91cdfe74Alex Klyubin    }
595970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton    if (option.equals("-proguard")) {
596970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton      return 2;
597970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton    }
598920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-proofread")) {
599920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
600920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
601920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-todo")) {
602920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
603920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
604920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-public")) {
605920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
606920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
607920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-protected")) {
608920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
609920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
610920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-package")) {
611920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
612920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
613920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-private")) {
614920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
615920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
616920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-hidden")) {
617920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
618920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
619920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-stubs")) {
620920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
621920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
622920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-stubpackages")) {
623920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
624920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
625920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-sdkvalues")) {
626920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
627920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
628040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato    if (option.equals("-api")) {
629920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
630920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
6315118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu    if (option.equals("-removedApi")) {
6325118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      return 2;
6335118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu    }
634920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-nodocs")) {
635920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
636920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
637e65daec66ebdf02baa00c0ee403321fa304f7ad5Dirk Dougherty    if (option.equals("-nodefaultassets")) {
638e65daec66ebdf02baa00c0ee403321fa304f7ad5Dirk Dougherty      return 1;
639e65daec66ebdf02baa00c0ee403321fa304f7ad5Dirk Dougherty    }
6409ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson    if (option.equals("-parsecomments")) {
6419ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson      return 1;
6429ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson    }
643920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-since")) {
644920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 3;
645920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
646920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-offlinemode")) {
647920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
648920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
649920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-federate")) {
650920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 3;
651920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
6521e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton    if (option.equals("-federationapi")) {
6531e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton      return 3;
6541e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton    }
65518b25554072c36d4d9652523ec15e0c5306101ceChirag Shah    if (option.equals("-yaml")) {
65618b25554072c36d4d9652523ec15e0c5306101ceChirag Shah      return 2;
65718b25554072c36d4d9652523ec15e0c5306101ceChirag Shah    }
6589b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    if (option.equals("-devsite")) {
6599b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      return 1;
6609b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    }
6615ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly    if (option.equals("-gmsref")) {
6625ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      gmsRef = true;
6635ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      return 1;
6645ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly    }
6655ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly    if (option.equals("-gcmref")) {
6665ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      gcmRef = true;
6675ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      return 1;
6685ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly    }
669c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty    if (option.equals("-metadataDebug")) {
670c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty      return 1;
671c770a6e2d78cacd7ad0290d8ff43fce8f8e5f000Dirk Dougherty    }
672b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson    if (option.equals("-documentannotations")) {
673b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson      return 2;
674b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson    }
675920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return 0;
676920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
677920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static boolean validOptions(String[][] options, DocErrorReporter r) {
678920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String[] a : options) {
679920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (a[0].equals("-error") || a[0].equals("-warning") || a[0].equals("-hide")) {
680920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        try {
681920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Integer.parseInt(a[1]);
682920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        } catch (NumberFormatException e) {
683920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          r.printError("bad -" + a[0] + " value must be a number: " + a[1]);
684920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return false;
685920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
686920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
687920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
688920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
689920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return true;
690920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
691920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
692920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static Data makeHDF() {
693920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = jSilver.createData();
694920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
695920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String[] p : mHDFData) {
696920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue(p[0], p[1]);
697920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
698920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
699920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return data;
700920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
701920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
702920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
703920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
704920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static Data makePackageHDF() {
705920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makeHDF();
706920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.rootClasses();
707920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
708920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    SortedMap<String, PackageInfo> sorted = new TreeMap<String, PackageInfo>();
709920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : classes) {
710920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      PackageInfo pkg = cl.containingPackage();
711920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String name;
712920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (pkg == null) {
713920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = "";
714920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
715920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = pkg.name();
716920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
717920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sorted.put(name, pkg);
718920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
719920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
720920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i = 0;
721f8e1e3910a9509eecb7eea99cf2d1c6a75699271C. Sean Young    for (Map.Entry<String, PackageInfo> entry : sorted.entrySet()) {
722f8e1e3910a9509eecb7eea99cf2d1c6a75699271C. Sean Young      String s = entry.getKey();
723f8e1e3910a9509eecb7eea99cf2d1c6a75699271C. Sean Young      PackageInfo pkg = entry.getValue();
724920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
7255118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      if (pkg.isHiddenOrRemoved()) {
726920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        continue;
727920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
7285118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      boolean allHiddenOrRemoved = true;
729920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      int pass = 0;
730920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo[] classesToCheck = null;
731700b9f275638190f24e83a91b5105255df7f7c11Brett Chabot      while (pass < 6) {
732920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        switch (pass) {
733920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 0:
734920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.ordinaryClasses();
735920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
736920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 1:
737920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.enums();
738920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
739920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 2:
740920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.errors();
741920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
742920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 3:
743920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.exceptions();
744920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
745920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 4:
746920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.interfaces();
747920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
748700b9f275638190f24e83a91b5105255df7f7c11Brett Chabot          case 5:
749700b9f275638190f24e83a91b5105255df7f7c11Brett Chabot            classesToCheck = pkg.annotations();
750700b9f275638190f24e83a91b5105255df7f7c11Brett Chabot            break;
751920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          default:
752920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            System.err.println("Error reading package: " + pkg.name());
753920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
754920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
755920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        for (ClassInfo cl : classesToCheck) {
7565118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu          if (!cl.isHiddenOrRemoved()) {
7575118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu            allHiddenOrRemoved = false;
758920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
759920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
760920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
7615118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu        if (!allHiddenOrRemoved) {
762920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          break;
763920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
764920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        pass++;
765920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
7665118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      if (allHiddenOrRemoved) {
767920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        continue;
768920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
7695ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      if(gmsRef){
7705ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly          data.setValue("reference.gms", "true");
7715ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      } else if(gcmRef){
7725ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly          data.setValue("reference.gcm", "true");
7735ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      }
774920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("reference", "1");
775920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("reference.apilevels", sinceTagger.hasVersions() ? "1" : "0");
776920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.packages." + i + ".name", s);
777920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.packages." + i + ".link", pkg.htmlPage());
778920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.packages." + i + ".since", pkg.getSince());
779920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      TagInfo.makeHDF(data, "docs.packages." + i + ".shortDescr", pkg.firstSentenceTags());
780920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      i++;
781920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
782920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
783920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    sinceTagger.writeVersionNames(data);
784920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return data;
785920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
786920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
787920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeDirectory(File dir, String relative, JSilver js) {
788920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    File[] files = dir.listFiles();
789920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i, count = files.length;
790920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (i = 0; i < count; i++) {
791920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      File f = files[i];
792920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (f.isFile()) {
793920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        String templ = relative + f.getName();
794920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        int len = templ.length();
795920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (len > 3 && ".cs".equals(templ.substring(len - 3))) {
796920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Data data = makeHDF();
797920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          String filename = templ.substring(0, len - 3) + htmlExtension;
798920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          ClearPage.write(data, templ, filename, js);
799920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        } else if (len > 3 && ".jd".equals(templ.substring(len - 3))) {
80042303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty          Data data = makeHDF();
801920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          String filename = templ.substring(0, len - 3) + htmlExtension;
80242303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty          DocFile.writePage(f.getAbsolutePath(), relative, filename, data);
80388c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly        } else if(!f.getName().equals(".DS_Store")){
80488c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly              Data data = makeHDF();
80588c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly              String hdfValue = data.getValue("sac") == null ? "" : data.getValue("sac");
80688c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly              boolean allowExcepted = hdfValue.equals("true") ? true : false;
80788c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly              ClearPage.copyFile(allowExcepted, f, templ);
808920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
809920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (f.isDirectory()) {
810920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeDirectory(f, relative + f.getName() + "/", js);
811920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
812920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
813920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
814920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
815920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeHTMLPages() {
8164bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier    for (String htmlDir : ClearPage.htmlDirs) {
8174bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      File f = new File(htmlDir);
8184bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      if (!f.isDirectory()) {
8194bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier        System.err.println("htmlDir not a directory: " + htmlDir);
8204bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier        continue;
8214bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      }
822920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
8234bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      ResourceLoader loader = new FileSystemResourceLoader(f);
8244bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      JSilver js = new JSilver(loader);
8254bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      writeDirectory(f, "", js);
8264bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier    }
827920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
828920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
829920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeAssets() {
830920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    JarFile thisJar = JarUtils.jarForClass(Doclava.class, null);
8319b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    if ((thisJar != null) && (includeDefaultAssets)) {
832920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
833920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        List<String> templateDirs = ClearPage.getBundledTemplateDirs();
834920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        for (String templateDir : templateDirs) {
835920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          String assetsDir = templateDir + "/assets";
836920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          JarUtils.copyResourcesToDirectory(thisJar, assetsDir, ClearPage.outputDir + "/assets");
837920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
838920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (IOException e) {
839920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        System.err.println("Error copying assets directory.");
840920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        e.printStackTrace();
841920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return;
842920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
843920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
844920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
8459b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    //write the project-specific assets
846920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    List<String> templateDirs = ClearPage.getTemplateDirs();
847920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String templateDir : templateDirs) {
848920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      File assets = new File(templateDir + "/assets");
849920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (assets.isDirectory()) {
850920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeDirectory(assets, "assets/", null);
851920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
852920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
8539b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty
8549b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    // Create the timestamp.js file based on .cs file
855460dd2aa33a4e4666eb05f7a26f335e2a012dbb7Scott Main    Data timedata = Doclava.makeHDF();
856460dd2aa33a4e4666eb05f7a26f335e2a012dbb7Scott Main    ClearPage.write(timedata, "timestamp.cs", "timestamp.js");
857920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
858920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
85971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  /** Go through the docs and generate meta-data about each
86071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      page to use in search suggestions */
861920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeLists() {
86271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
86371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    // Write the lists for API references
864920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makeHDF();
865920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
866920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.rootClasses();
867920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
868920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    SortedMap<String, Object> sorted = new TreeMap<String, Object>();
869920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : classes) {
8705118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      if (cl.isHiddenOrRemoved()) {
871920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        continue;
872920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
873920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sorted.put(cl.qualifiedName(), cl);
874920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      PackageInfo pkg = cl.containingPackage();
875920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String name;
876920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (pkg == null) {
877920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = "";
878920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
879920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = pkg.name();
880920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
881920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sorted.put(name, pkg);
882920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
883920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
884920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i = 0;
885920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String s : sorted.keySet()) {
886920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.pages." + i + ".id", "" + i);
887920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.pages." + i + ".label", s);
888920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
889920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Object o = sorted.get(s);
890920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (o instanceof PackageInfo) {
891920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        PackageInfo pkg = (PackageInfo) o;
892920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        data.setValue("docs.pages." + i + ".link", pkg.htmlPage());
893920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        data.setValue("docs.pages." + i + ".type", "package");
89468a238ae4243e6f0f2a370b8b915ef0686ca0b37Scott Main        data.setValue("docs.pages." + i + ".deprecated", pkg.isDeprecated() ? "true" : "false");
895920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (o instanceof ClassInfo) {
896920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ClassInfo cl = (ClassInfo) o;
897920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        data.setValue("docs.pages." + i + ".link", cl.htmlPage());
898920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        data.setValue("docs.pages." + i + ".type", "class");
89968a238ae4243e6f0f2a370b8b915ef0686ca0b37Scott Main        data.setValue("docs.pages." + i + ".deprecated", cl.isDeprecated() ? "true" : "false");
900920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
901920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      i++;
902920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
90357657b935a6aefc36b2a7f5704665e4da818c3e6Robert Ly    ClearPage.write(data, "lists.cs", javadocDir + "lists.js");
90471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
90571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
9067791802d9b43c2067b566bf81667096ed91decb8Scott Main    // Write the lists for JD documents (if there are HTML directories to process)
9077791802d9b43c2067b566bf81667096ed91decb8Scott Main    if (inputPathHtmlDirs.size() > 0) {
9087791802d9b43c2067b566bf81667096ed91decb8Scott Main      Data jddata = makeHDF();
9097791802d9b43c2067b566bf81667096ed91decb8Scott Main      Iterator counter = new Iterator();
9107791802d9b43c2067b566bf81667096ed91decb8Scott Main      for (String htmlDir : inputPathHtmlDirs) {
9117791802d9b43c2067b566bf81667096ed91decb8Scott Main        File dir = new File(htmlDir);
9127791802d9b43c2067b566bf81667096ed91decb8Scott Main        if (!dir.isDirectory()) {
9137791802d9b43c2067b566bf81667096ed91decb8Scott Main          continue;
9147791802d9b43c2067b566bf81667096ed91decb8Scott Main        }
9157791802d9b43c2067b566bf81667096ed91decb8Scott Main        writeJdDirList(dir, jddata, counter);
91671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      }
9177791802d9b43c2067b566bf81667096ed91decb8Scott Main      ClearPage.write(jddata, "jd_lists.cs", javadocDir + "jd_lists.js");
91871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    }
91971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  }
92071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
92171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  private static class Iterator {
92271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    int i = 0;
92371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  }
92471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
92571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  /** Write meta-data for a JD file, used for search suggestions */
92671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  private static void writeJdDirList(File dir, Data data, Iterator counter) {
92771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    File[] files = dir.listFiles();
92871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    int i, count = files.length;
92971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    // Loop all files in given directory
93071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    for (i = 0; i < count; i++) {
93171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      File f = files[i];
93271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      if (f.isFile()) {
93371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        String filePath = f.getAbsolutePath();
93471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        String templ = f.getName();
93571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        int len = templ.length();
93671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        // If it's a .jd file we want to process
93771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        if (len > 3 && ".jd".equals(templ.substring(len - 3))) {
93871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          // remove the directories below the site root
9395118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu          String webPath = filePath.substring(filePath.indexOf("docs/html/") + 10,
9405118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu              filePath.length());
94171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          // replace .jd with .html
94271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          webPath = webPath.substring(0, webPath.length() - 3) + htmlExtension;
94371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          // Parse the .jd file for properties data at top of page
94471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          Data hdf = Doclava.makeHDF();
94571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          String filedata = DocFile.readFile(filePath);
94671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          Matcher lines = DocFile.LINE.matcher(filedata);
94771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          String line = null;
94871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          // Get each line to add the key-value to hdf
94971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          while (lines.find()) {
95071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            line = lines.group(1);
95171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            if (line.length() > 0) {
95271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              // Stop when we hit the body
95371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              if (line.equals("@jd:body")) {
95471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                break;
95571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              }
95671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              Matcher prop = DocFile.PROP.matcher(line);
95771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              if (prop.matches()) {
95871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                String key = prop.group(1);
95971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                String value = prop.group(2);
96071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                hdf.setValue(key, value);
96171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              } else {
96271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                break;
96371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              }
96471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            }
96571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          } // done gathering page properties
96671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
96771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          // Insert the goods into HDF data (title, link, tags, type)
96871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          String title = hdf.getValue("page.title", "");
9699950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main          title = title.replaceAll("\"", "'");
9709950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main          // if there's a <span> in the title, get rid of it
9719950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main          if (title.indexOf("<span") != -1) {
9729950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main            String[] splitTitle = title.split("<span(.*?)</span>");
9739950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main            title = splitTitle[0];
9749950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main            for (int j = 1; j < splitTitle.length; j++) {
9759950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main              title.concat(splitTitle[j]);
9769950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main            }
9779950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main          }
978b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty
979b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty          StringBuilder tags =  new StringBuilder();
98042303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty          String tagsList = hdf.getValue("page.tags", "");
98142303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty          if (!tagsList.equals("")) {
98242303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty            tagsList = tagsList.replaceAll("\"", "");
98342303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty            String[] tagParts = tagsList.split(",");
984b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty            for (int iter = 0; iter < tagParts.length; iter++) {
985b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty              tags.append("\"");
986b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty              tags.append(tagParts[iter].trim());
987b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty              tags.append("\"");
988b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty              if (iter < tagParts.length - 1) {
989b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty                tags.append(",");
990b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty              }
991b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty            }
992b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty          }
993b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty
99471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          String dirName = (webPath.indexOf("/") != -1)
99571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                  ? webPath.substring(0, webPath.indexOf("/")) : "";
99671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
997489864e7dd2eee3f6a90919e5084964ad4d8b3c7Scott Main          if (!"".equals(title) &&
998489864e7dd2eee3f6a90919e5084964ad4d8b3c7Scott Main              !"intl".equals(dirName) &&
999489864e7dd2eee3f6a90919e5084964ad4d8b3c7Scott Main              !hdf.getBooleanValue("excludeFromSuggestions")) {
10009950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main            data.setValue("docs.pages." + counter.i + ".label", title);
100171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            data.setValue("docs.pages." + counter.i + ".link", webPath);
1002b4d562baab474d1c96a81cc6dc9e3e3a543a91c2Dirk Dougherty            data.setValue("docs.pages." + counter.i + ".tags", tags.toString());
100371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            data.setValue("docs.pages." + counter.i + ".type", dirName);
100471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            counter.i++;
100571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          }
100671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        }
100771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      } else if (f.isDirectory()) {
100871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        writeJdDirList(f, data, counter);
100971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      }
101071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    }
1011920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1012920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1013920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void cantStripThis(ClassInfo cl, HashSet<ClassInfo> notStrippable) {
1014920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (!notStrippable.add(cl)) {
1015920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // slight optimization: if it already contains cl, it already contains
1016920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // all of cl's parents
1017920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return;
1018920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1019920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo supr = cl.superclass();
1020920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (supr != null) {
1021920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      cantStripThis(supr, notStrippable);
1022920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1023920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo iface : cl.interfaces()) {
1024920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      cantStripThis(iface, notStrippable);
1025920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1026920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1027920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1028920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static String getPrintableName(ClassInfo cl) {
1029920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo containingClass = cl.containingClass();
1030920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (containingClass != null) {
1031920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // This is an inner class.
1032920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String baseName = cl.name();
1033920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      baseName = baseName.substring(baseName.lastIndexOf('.') + 1);
1034920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return getPrintableName(containingClass) + '$' + baseName;
1035920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1036920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return cl.qualifiedName();
1037920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1038920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1039920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1040920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Writes the list of classes that must be present in order to provide the non-hidden APIs known
1041920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * to javadoc.
10423c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1043920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param filename the path to the file to write the list to
1044920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1045920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeKeepList(String filename) {
1046920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    HashSet<ClassInfo> notStrippable = new HashSet<ClassInfo>();
1047920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] all = Converter.allClasses();
1048920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Arrays.sort(all); // just to make the file a little more readable
1049920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1050920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // If a class is public and not hidden, then it and everything it derives
1051920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // from cannot be stripped. Otherwise we can strip it.
1052920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : all) {
10535118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      if (cl.isPublic() && !cl.isHiddenOrRemoved()) {
1054920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        cantStripThis(cl, notStrippable);
1055920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1056920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1057920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    PrintStream stream = null;
1058920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    try {
1059ed8f79791885c3ac15401d88a147aee551e1039eBrian Carlstrom      stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(filename)));
1060920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (ClassInfo cl : notStrippable) {
1061920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        stream.println(getPrintableName(cl));
1062920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1063920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } catch (FileNotFoundException e) {
1064920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      System.err.println("error writing file: " + filename);
1065920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } finally {
1066920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (stream != null) {
1067920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        stream.close();
1068920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1069920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1070920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1071920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1072920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static PackageInfo[] sVisiblePackages = null;
1073920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1074920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static PackageInfo[] choosePackages() {
1075920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (sVisiblePackages != null) {
1076920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return sVisiblePackages;
1077920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1078920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1079920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.rootClasses();
1080920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    SortedMap<String, PackageInfo> sorted = new TreeMap<String, PackageInfo>();
1081920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : classes) {
1082920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      PackageInfo pkg = cl.containingPackage();
1083920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String name;
1084920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (pkg == null) {
1085920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = "";
1086920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
1087920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = pkg.name();
1088920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1089920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sorted.put(name, pkg);
1090920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1091920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1092920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<PackageInfo> result = new ArrayList<PackageInfo>();
1093920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1094920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String s : sorted.keySet()) {
1095920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      PackageInfo pkg = sorted.get(s);
1096920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
10975118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      if (pkg.isHiddenOrRemoved()) {
1098920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        continue;
1099920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
11005118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu
11015118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      boolean allHiddenOrRemoved = true;
1102920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      int pass = 0;
1103920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo[] classesToCheck = null;
1104700b9f275638190f24e83a91b5105255df7f7c11Brett Chabot      while (pass < 6) {
1105920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        switch (pass) {
1106920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 0:
1107920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.ordinaryClasses();
1108920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1109920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 1:
1110920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.enums();
1111920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1112920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 2:
1113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.errors();
1114920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1115920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 3:
1116920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.exceptions();
1117920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1118920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 4:
1119920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.interfaces();
1120920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1121700b9f275638190f24e83a91b5105255df7f7c11Brett Chabot          case 5:
1122700b9f275638190f24e83a91b5105255df7f7c11Brett Chabot            classesToCheck = pkg.annotations();
1123700b9f275638190f24e83a91b5105255df7f7c11Brett Chabot            break;
1124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          default:
1125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            System.err.println("Error reading package: " + pkg.name());
1126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1127920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        for (ClassInfo cl : classesToCheck) {
11295118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu          if (!cl.isHiddenOrRemoved()) {
11305118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu            allHiddenOrRemoved = false;
1131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
1133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
11345118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu        if (!allHiddenOrRemoved) {
1135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          break;
1136920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1137920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        pass++;
1138920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
11395118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      if (allHiddenOrRemoved) {
1140920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        continue;
1141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1142920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1143920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      result.add(pkg);
1144920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1145920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1146920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    sVisiblePackages = result.toArray(new PackageInfo[result.size()]);
1147920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return sVisiblePackages;
1148920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1149920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1150920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writePackages(String filename) {
1151920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makePackageHDF();
1152920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1153920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i = 0;
1154920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (PackageInfo pkg : choosePackages()) {
1155920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      writePackage(pkg);
1156920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1157920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.packages." + i + ".name", pkg.name());
1158920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.packages." + i + ".link", pkg.htmlPage());
1159920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      TagInfo.makeHDF(data, "docs.packages." + i + ".shortDescr", pkg.firstSentenceTags());
1160920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1161920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      i++;
1162920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1163920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1164920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    setPageTitle(data, "Package Index");
1165920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1166920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo.makeHDF(data, "root.descr", Converter.convertTags(root.inlineTags(), null));
1167920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1168920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "packages.cs", filename);
1169920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "package-list.cs", javadocDir + "package-list");
1170920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1171920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Proofread.writePackages(filename, Converter.convertTags(root.inlineTags(), null));
1172920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1173920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1174920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writePackage(PackageInfo pkg) {
1175920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // these this and the description are in the same directory,
1176920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // so it's okay
1177920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makePackageHDF();
1178920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1179920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String name = pkg.name();
1180920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1181920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue("package.name", name);
1182920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue("package.since", pkg.getSince());
1183920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue("package.descr", "...description...");
1184920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    pkg.setFederatedReferences(data, "package");
1185920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1186700b9f275638190f24e83a91b5105255df7f7c11Brett Chabot    makeClassListHDF(data, "package.annotations", ClassInfo.sortByName(pkg.annotations()));
1187920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeClassListHDF(data, "package.interfaces", ClassInfo.sortByName(pkg.interfaces()));
1188920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeClassListHDF(data, "package.classes", ClassInfo.sortByName(pkg.ordinaryClasses()));
1189920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeClassListHDF(data, "package.enums", ClassInfo.sortByName(pkg.enums()));
1190920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeClassListHDF(data, "package.exceptions", ClassInfo.sortByName(pkg.exceptions()));
1191920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeClassListHDF(data, "package.errors", ClassInfo.sortByName(pkg.errors()));
1192920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo.makeHDF(data, "package.shortDescr", pkg.firstSentenceTags());
1193920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo.makeHDF(data, "package.descr", pkg.inlineTags());
1194920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1195920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String filename = pkg.htmlPage();
1196920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    setPageTitle(data, name);
1197920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "package.cs", filename);
1198920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1199920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Proofread.writePackage(filename, pkg.inlineTags());
1200920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1201920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1202920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeClassLists() {
1203920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i;
1204920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makePackageHDF();
1205920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
12065118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu    ClassInfo[] classes = PackageInfo.filterHiddenAndRemoved(
12075118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu        Converter.convertClasses(root.classes()));
1208920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (classes.length == 0) {
1209920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return;
1210920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1211920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1212920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Sorter[] sorted = new Sorter[classes.length];
1213920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (i = 0; i < sorted.length; i++) {
1214920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo cl = classes[i];
1215920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String name = cl.name();
1216920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sorted[i] = new Sorter(name, cl);
1217920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1218920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1219920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Arrays.sort(sorted);
1220920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1221920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // make a pass and resolve ones that have the same name
1222920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int firstMatch = 0;
1223920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String lastName = sorted[0].label;
1224920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (i = 1; i < sorted.length; i++) {
1225920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String s = sorted[i].label;
1226920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (!lastName.equals(s)) {
1227920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (firstMatch != i - 1) {
1228920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          // there were duplicates
1229920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          for (int j = firstMatch; j < i; j++) {
1230920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            PackageInfo pkg = ((ClassInfo) sorted[j].data).containingPackage();
1231920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            if (pkg != null) {
1232920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              sorted[j].label = sorted[j].label + " (" + pkg.name() + ")";
1233920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            }
1234920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
1235920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1236920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        firstMatch = i;
1237920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        lastName = s;
1238920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1239920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1240920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1241920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // and sort again
1242920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Arrays.sort(sorted);
1243920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1244920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (i = 0; i < sorted.length; i++) {
1245920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String s = sorted[i].label;
1246920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo cl = (ClassInfo) sorted[i].data;
1247920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      char first = Character.toUpperCase(s.charAt(0));
1248920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      cl.makeShortDescrHDF(data, "docs.classes." + first + '.' + i);
1249920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1250920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1251920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    setPageTitle(data, "Class Index");
1252920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "classes.cs", javadocDir + "classes" + htmlExtension);
1253920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1254920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1255920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  // we use the word keywords because "index" means something else in html land
1256920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  // the user only ever sees the word index
1257920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /*
1258920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * public static void writeKeywords() { ArrayList<KeywordEntry> keywords = new
1259920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * ArrayList<KeywordEntry>();
12603c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
12615118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu   * ClassInfo[] classes = PackageInfo.filterHiddenAndRemoved(Converter.convertClasses(root.classes()));
12623c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1263920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * for (ClassInfo cl: classes) { cl.makeKeywordEntries(keywords); }
12643c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1265920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * HDF data = makeHDF();
12663c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1267920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Collections.sort(keywords);
12683c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1269920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * int i=0; for (KeywordEntry entry: keywords) { String base = "keywords." + entry.firstChar() +
1270920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * "." + i; entry.makeHDF(data, base); i++; }
12713c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1272920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * setPageTitle(data, "Index"); ClearPage.write(data, "keywords.cs", javadocDir + "keywords" +
1273920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * htmlExtension); }
1274920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1275920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1276920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeHierarchy() {
1277920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.rootClasses();
1278920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> info = new ArrayList<ClassInfo>();
1279920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : classes) {
12805118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      if (!cl.isHiddenOrRemoved()) {
1281920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        info.add(cl);
1282920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1283920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1284920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makePackageHDF();
1285920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Hierarchy.makeHierarchy(data, info.toArray(new ClassInfo[info.size()]));
1286920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    setPageTitle(data, "Class Hierarchy");
1287920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "hierarchy.cs", javadocDir + "hierarchy" + htmlExtension);
1288920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1289920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1290920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeClasses() {
1291920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.rootClasses();
1292920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1293920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : classes) {
1294920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Data data = makePackageHDF();
12955118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      if (!cl.isHiddenOrRemoved()) {
1296920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeClass(cl, data);
1297920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1298920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1299920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1300920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1301920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeClass(ClassInfo cl, Data data) {
1302920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    cl.makeHDF(data);
1303920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    setPageTitle(data, cl.name());
13049b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    String outfile = cl.htmlPage();
13059b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    ClearPage.write(data, "class.cs", outfile);
1306920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Proofread.writeClass(cl.htmlPage(), cl);
1307920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1308920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1309920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void makeClassListHDF(Data data, String base, ClassInfo[] classes) {
1310920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < classes.length; i++) {
1311920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo cl = classes[i];
13125118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      if (!cl.isHiddenOrRemoved()) {
1313920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        cl.makeShortDescrHDF(data, base + "." + i);
1314920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1315920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1316920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1317920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1318920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static String linkTarget(String source, String target) {
1319920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String[] src = source.split("/");
1320920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String[] tgt = target.split("/");
1321920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1322920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int srclen = src.length;
1323920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int tgtlen = tgt.length;
1324920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1325920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int same = 0;
1326920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    while (same < (srclen - 1) && same < (tgtlen - 1) && (src[same].equals(tgt[same]))) {
1327920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      same++;
1328920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1329920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1330920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String s = "";
1331920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1332920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int up = srclen - same - 1;
1333920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < up; i++) {
1334920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      s += "../";
1335920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1336920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1337920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1338920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int N = tgtlen - 1;
1339920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = same; i < N; i++) {
1340920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      s += tgt[i] + '/';
1341920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1342920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    s += tgt[tgtlen - 1];
1343920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1344920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return s;
1345920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1346920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1347920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
13485118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu   * Returns true if the given element has an @hide, @removed or @pending annotation.
1349920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
13505118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu  private static boolean hasHideOrRemovedAnnotation(Doc doc) {
1351920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String comment = doc.getRawCommentText();
13525118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu    return comment.indexOf("@hide") != -1 || comment.indexOf("@pending") != -1 ||
13535118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu        comment.indexOf("@removed") != -1;
1354920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1355920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1356920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1357920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Returns true if the given element is hidden.
1358920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
13595118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu  private static boolean isHiddenOrRemoved(Doc doc) {
1360920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Methods, fields, constructors.
1361920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (doc instanceof MemberDoc) {
13625118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      return hasHideOrRemovedAnnotation(doc);
1363920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1364920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1365920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Classes, interfaces, enums, annotation types.
1366920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (doc instanceof ClassDoc) {
1367920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassDoc classDoc = (ClassDoc) doc;
1368920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1369920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Check the containing package.
13705118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      if (hasHideOrRemovedAnnotation(classDoc.containingPackage())) {
1371920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return true;
1372920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1373920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1374920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Check the class doc and containing class docs if this is a
1375920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // nested class.
1376920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassDoc current = classDoc;
1377920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      do {
13785118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu        if (hasHideOrRemovedAnnotation(current)) {
1379920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return true;
1380920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1381920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1382920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        current = current.containingClass();
1383920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } while (current != null);
1384920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1385920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1386920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return false;
1387920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1388920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1389920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
13905118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu   * Filters out hidden and removed elements.
1391920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
13925118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu  private static Object filterHiddenAndRemoved(Object o, Class<?> expected) {
1393920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (o == null) {
1394920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return null;
1395920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1396920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1397920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Class type = o.getClass();
1398920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (type.getName().startsWith("com.sun.")) {
1399920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // TODO: Implement interfaces from superclasses, too.
1400920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return Proxy
1401920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          .newProxyInstance(type.getClassLoader(), type.getInterfaces(), new HideHandler(o));
1402920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else if (o instanceof Object[]) {
1403920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Class<?> componentType = expected.getComponentType();
1404920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Object[] array = (Object[]) o;
1405920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      List<Object> list = new ArrayList<Object>(array.length);
1406920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (Object entry : array) {
14075118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu        if ((entry instanceof Doc) && isHiddenOrRemoved((Doc) entry)) {
1408920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          continue;
1409920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
14105118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu        list.add(filterHiddenAndRemoved(entry, componentType));
1411920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1412920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return list.toArray((Object[]) Array.newInstance(componentType, list.size()));
1413920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else {
1414920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return o;
1415920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1416920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1417920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1418920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1419920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Filters hidden elements out of method return values.
1420920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1421920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static class HideHandler implements InvocationHandler {
1422920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1423920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    private final Object target;
1424920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1425920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    public HideHandler(Object target) {
1426920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      this.target = target;
1427920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1428920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1429920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
1430920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String methodName = method.getName();
1431920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (args != null) {
1432920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (methodName.equals("compareTo") || methodName.equals("equals")
1433920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            || methodName.equals("overrides") || methodName.equals("subclassOf")) {
1434920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          args[0] = unwrap(args[0]);
1435920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1436920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1437920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1438920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (methodName.equals("getRawCommentText")) {
1439920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return filterComment((String) method.invoke(target, args));
1440920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1441920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1442920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // escape "&" in disjunctive types.
1443920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (proxy instanceof Type && methodName.equals("toString")) {
1444920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return ((String) method.invoke(target, args)).replace("&", "&amp;");
1445920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1446920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1447920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
14485118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu        return filterHiddenAndRemoved(method.invoke(target, args), method.getReturnType());
1449920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (InvocationTargetException e) {
1450920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        throw e.getTargetException();
1451920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1452920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1453920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1454920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    private String filterComment(String s) {
1455920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (s == null) {
1456920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return null;
1457920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1458920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1459920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      s = s.trim();
1460920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1461920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Work around off by one error
1462920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      while (s.length() >= 5 && s.charAt(s.length() - 5) == '{') {
1463920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        s += "&nbsp;";
1464920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1465920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1466920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return s;
1467920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1468920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1469920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    private static Object unwrap(Object proxy) {
1470920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (proxy instanceof Proxy) return ((HideHandler) Proxy.getInvocationHandler(proxy)).target;
1471920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return proxy;
1472920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1473920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1474920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1475920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1476920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Collect the values used by the Dev tools and write them in files packaged with the SDK
14773c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1478920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param output the ouput directory for the files.
1479920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1480920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeSdkValues(String output) {
1481920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<String> activityActions = new ArrayList<String>();
1482920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<String> broadcastActions = new ArrayList<String>();
1483920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<String> serviceActions = new ArrayList<String>();
1484920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<String> categories = new ArrayList<String>();
1485920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<String> features = new ArrayList<String>();
1486920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1487920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> layouts = new ArrayList<ClassInfo>();
1488920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> widgets = new ArrayList<ClassInfo>();
1489920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> layoutParams = new ArrayList<ClassInfo>();
1490920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1491920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.allClasses();
1492920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1493df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta    // The topmost LayoutParams class - android.view.ViewGroup.LayoutParams
1494df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta    ClassInfo topLayoutParams = null;
1495df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta
1496920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Go through all the fields of all the classes, looking SDK stuff.
1497920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo clazz : classes) {
1498920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1499920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // first check constant fields for the SdkConstant annotation.
1500d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      ArrayList<FieldInfo> fields = clazz.allSelfFields();
1501920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (FieldInfo field : fields) {
1502920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        Object cValue = field.constantValue();
1503920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (cValue != null) {
1504d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            ArrayList<AnnotationInstanceInfo> annotations = field.annotations();
1505d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein          if (!annotations.isEmpty()) {
1506920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            for (AnnotationInstanceInfo annotation : annotations) {
1507920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              if (SDK_CONSTANT_ANNOTATION.equals(annotation.type().qualifiedName())) {
1508d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                if (!annotation.elementValues().isEmpty()) {
1509d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                  String type = annotation.elementValues().get(0).valueString();
1510920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  if (SDK_CONSTANT_TYPE_ACTIVITY_ACTION.equals(type)) {
1511920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                    activityActions.add(cValue.toString());
1512920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  } else if (SDK_CONSTANT_TYPE_BROADCAST_ACTION.equals(type)) {
1513920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                    broadcastActions.add(cValue.toString());
1514920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  } else if (SDK_CONSTANT_TYPE_SERVICE_ACTION.equals(type)) {
1515920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                    serviceActions.add(cValue.toString());
1516920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  } else if (SDK_CONSTANT_TYPE_CATEGORY.equals(type)) {
1517920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                    categories.add(cValue.toString());
1518920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  } else if (SDK_CONSTANT_TYPE_FEATURE.equals(type)) {
1519920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                    features.add(cValue.toString());
1520920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  }
1521920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                }
1522920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                break;
1523920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              }
1524920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            }
1525920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
1526920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1527920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1528920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1529920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Now check the class for @Widget or if its in the android.widget package
1530920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // (unless the class is hidden or abstract, or non public)
15315118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu      if (clazz.isHiddenOrRemoved() == false && clazz.isPublic() && clazz.isAbstract() == false) {
1532920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        boolean annotated = false;
1533d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        ArrayList<AnnotationInstanceInfo> annotations = clazz.annotations();
1534d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        if (!annotations.isEmpty()) {
1535920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          for (AnnotationInstanceInfo annotation : annotations) {
1536920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            if (SDK_WIDGET_ANNOTATION.equals(annotation.type().qualifiedName())) {
1537920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              widgets.add(clazz);
1538920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              annotated = true;
1539920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              break;
1540920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            } else if (SDK_LAYOUT_ANNOTATION.equals(annotation.type().qualifiedName())) {
1541920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              layouts.add(clazz);
1542920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              annotated = true;
1543920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              break;
1544920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            }
1545920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
1546920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1547920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1548920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (annotated == false) {
1549df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta          if (topLayoutParams == null
1550df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta              && "android.view.ViewGroup.LayoutParams".equals(clazz.qualifiedName())) {
1551df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta            topLayoutParams = clazz;
1552df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta          }
1553df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta          // let's check if this is inside android.widget or android.view
1554df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta          if (isIncludedPackage(clazz)) {
1555920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            // now we check what this class inherits either from android.view.ViewGroup
1556920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            // or android.view.View, or android.view.ViewGroup.LayoutParams
1557920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            int type = checkInheritance(clazz);
1558920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            switch (type) {
1559920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              case TYPE_WIDGET:
1560920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                widgets.add(clazz);
1561920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                break;
1562920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              case TYPE_LAYOUT:
1563920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                layouts.add(clazz);
1564920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                break;
1565920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              case TYPE_LAYOUT_PARAM:
1566920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                layoutParams.add(clazz);
1567920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                break;
1568920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            }
1569920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
1570920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1571920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1572920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1573920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1574920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // now write the files, whether or not the list are empty.
1575920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // the SDK built requires those files to be present.
1576920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1577920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Collections.sort(activityActions);
1578920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeValues(output + "/activity_actions.txt", activityActions);
1579920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1580920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Collections.sort(broadcastActions);
1581920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeValues(output + "/broadcast_actions.txt", broadcastActions);
1582920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1583920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Collections.sort(serviceActions);
1584920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeValues(output + "/service_actions.txt", serviceActions);
1585920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1586920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Collections.sort(categories);
1587920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeValues(output + "/categories.txt", categories);
1588920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1589920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Collections.sort(features);
1590920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeValues(output + "/features.txt", features);
1591920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1592920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // before writing the list of classes, we do some checks, to make sure the layout params
1593920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // are enclosed by a layout class (and not one that has been declared as a widget)
1594920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < layoutParams.size();) {
1595df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta      ClassInfo clazz = layoutParams.get(i);
1596df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta      ClassInfo containingClass = clazz.containingClass();
1597df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta      boolean remove = containingClass == null || layouts.indexOf(containingClass) == -1;
1598df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta      // Also ensure that super classes of the layout params are in android.widget or android.view.
1599df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta      while (!remove && (clazz = clazz.superclass()) != null && !clazz.equals(topLayoutParams)) {
1600df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta        remove = !isIncludedPackage(clazz);
1601df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta      }
1602df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta      if (remove) {
1603920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        layoutParams.remove(i);
1604920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
1605920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        i++;
1606920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1607920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1608920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1609920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeClasses(output + "/widgets.txt", widgets, layouts, layoutParams);
1610920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1611920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1612920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1613df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta   * Check if the clazz is in package android.view or android.widget
1614df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta   */
1615df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta  private static boolean isIncludedPackage(ClassInfo clazz) {
1616df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta    String pckg = clazz.containingPackage().name();
1617df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta    return "android.widget".equals(pckg) || "android.view".equals(pckg);
1618df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta  }
1619df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta
1620df8d48b6dab0a1d5f354266e6617877f177894cfDeepanshu Gupta  /**
1621920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Writes a list of values into a text files.
16223c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1623920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param pathname the absolute os path of the output file.
1624920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param values the list of values to write.
1625920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1626920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeValues(String pathname, ArrayList<String> values) {
1627920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    FileWriter fw = null;
1628920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    BufferedWriter bw = null;
1629920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    try {
1630920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      fw = new FileWriter(pathname, false);
1631920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      bw = new BufferedWriter(fw);
1632920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1633920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (String value : values) {
1634920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        bw.append(value).append('\n');
1635920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1636920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } catch (IOException e) {
1637920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // pass for now
1638920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } finally {
1639920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
1640920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (bw != null) bw.close();
1641920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (IOException e) {
1642920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // pass for now
1643920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1644920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
1645920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (fw != null) fw.close();
1646920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (IOException e) {
1647920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // pass for now
1648920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1649920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1650920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1651920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1652920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1653920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Writes the widget/layout/layout param classes into a text files.
16543c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1655920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param pathname the absolute os path of the output file.
1656920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param widgets the list of widget classes to write.
1657920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param layouts the list of layout classes to write.
1658920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param layoutParams the list of layout param classes to write.
1659920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1660920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeClasses(String pathname, ArrayList<ClassInfo> widgets,
1661920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ArrayList<ClassInfo> layouts, ArrayList<ClassInfo> layoutParams) {
1662920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    FileWriter fw = null;
1663920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    BufferedWriter bw = null;
1664920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    try {
1665920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      fw = new FileWriter(pathname, false);
1666920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      bw = new BufferedWriter(fw);
1667920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1668920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // write the 3 types of classes.
1669920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (ClassInfo clazz : widgets) {
1670920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeClass(bw, clazz, 'W');
1671920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1672920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (ClassInfo clazz : layoutParams) {
1673920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeClass(bw, clazz, 'P');
1674920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1675920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (ClassInfo clazz : layouts) {
1676920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeClass(bw, clazz, 'L');
1677920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1678920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } catch (IOException e) {
1679920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // pass for now
1680920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } finally {
1681920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
1682920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (bw != null) bw.close();
1683920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (IOException e) {
1684920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // pass for now
1685920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1686920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
1687920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (fw != null) fw.close();
1688920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (IOException e) {
1689920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // pass for now
1690920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1691920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1692920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1693920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1694920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1695920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Writes a class name and its super class names into a {@link BufferedWriter}.
16963c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1697920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param writer the BufferedWriter to write into
1698920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param clazz the class to write
1699920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param prefix the prefix to put at the beginning of the line.
1700920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @throws IOException
1701920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1702920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeClass(BufferedWriter writer, ClassInfo clazz, char prefix)
1703920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      throws IOException {
1704920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writer.append(prefix).append(clazz.qualifiedName());
1705920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo superClass = clazz;
1706920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    while ((superClass = superClass.superclass()) != null) {
1707920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      writer.append(' ').append(superClass.qualifiedName());
1708920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1709920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writer.append('\n');
1710920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1711920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1712920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1713920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Checks the inheritance of {@link ClassInfo} objects. This method return
1714920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <ul>
1715920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <li>{@link #TYPE_LAYOUT}: if the class extends <code>android.view.ViewGroup</code></li>
1716920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <li>{@link #TYPE_WIDGET}: if the class extends <code>android.view.View</code></li>
1717920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <li>{@link #TYPE_LAYOUT_PARAM}: if the class extends
1718920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <code>android.view.ViewGroup$LayoutParams</code></li>
1719920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <li>{@link #TYPE_NONE}: in all other cases</li>
1720920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * </ul>
17213c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1722920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param clazz the {@link ClassInfo} to check.
1723920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1724920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static int checkInheritance(ClassInfo clazz) {
1725920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if ("android.view.ViewGroup".equals(clazz.qualifiedName())) {
1726920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return TYPE_LAYOUT;
1727920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else if ("android.view.View".equals(clazz.qualifiedName())) {
1728920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return TYPE_WIDGET;
1729920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else if ("android.view.ViewGroup.LayoutParams".equals(clazz.qualifiedName())) {
1730920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return TYPE_LAYOUT_PARAM;
1731920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1732920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1733920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo parent = clazz.superclass();
1734920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (parent != null) {
1735920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return checkInheritance(parent);
1736920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1737920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1738920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return TYPE_NONE;
1739920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
174018b25554072c36d4d9652523ec15e0c5306101ceChirag Shah
174118b25554072c36d4d9652523ec15e0c5306101ceChirag Shah  /**
174218b25554072c36d4d9652523ec15e0c5306101ceChirag Shah   * Ensures a trailing '/' at the end of a string.
174318b25554072c36d4d9652523ec15e0c5306101ceChirag Shah   */
174418b25554072c36d4d9652523ec15e0c5306101ceChirag Shah  static String ensureSlash(String path) {
174518b25554072c36d4d9652523ec15e0c5306101ceChirag Shah    return path.endsWith("/") ? path : path + "/";
174618b25554072c36d4d9652523ec15e0c5306101ceChirag Shah  }
17471b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
17481b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  /**
17497537229470687560714401104558abdf82f81441Dirk Dougherty  * Process sample projects. Generate the TOC for the samples groups and project
17507537229470687560714401104558abdf82f81441Dirk Dougherty  * and write it to a cs var, which is then written to files during templating to
17517537229470687560714401104558abdf82f81441Dirk Dougherty  * html output. Collect metadata from sample project _index.jd files. Copy html
17527537229470687560714401104558abdf82f81441Dirk Dougherty  * and specific source file types to the output directory.
17531b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  */
1754815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty  public static void writeSamples(boolean offlineMode, ArrayList<SampleCode> sampleCodes,
1755815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      boolean sortNavByGroups) {
17567537229470687560714401104558abdf82f81441Dirk Dougherty    samplesNavTree = makeHDF();
17577537229470687560714401104558abdf82f81441Dirk Dougherty
17587537229470687560714401104558abdf82f81441Dirk Dougherty    // Go through samples processing files. Create a root list for SC nodes,
17591b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    // pass it to SCs for their NavTree children and append them.
17601b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    List<SampleCode.Node> samplesList = new ArrayList<SampleCode.Node>();
1761815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    List<SampleCode.Node> sampleGroupsRootNodes = null;
17621b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    for (SampleCode sc : sampleCodes) {
17637537229470687560714401104558abdf82f81441Dirk Dougherty      samplesList.add(sc.setSamplesTOC(offlineMode));
17647537229470687560714401104558abdf82f81441Dirk Dougherty     }
1765815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    if (sortNavByGroups) {
1766815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      sampleGroupsRootNodes = new ArrayList<SampleCode.Node>();
1767815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      for (SampleCode gsc : sampleCodeGroups) {
17687537229470687560714401104558abdf82f81441Dirk Dougherty        String link =  ClearPage.toroot + "samples/" + gsc.mTitle.replaceAll(" ", "").trim().toLowerCase() + ".html";
176942303ccef18dc4492dc668a020197bc6b1956cbcDirk Dougherty        sampleGroupsRootNodes.add(new SampleCode.Node.Builder().setLabel(gsc.mTitle).setLink(link).setType("groupholder").build());
1770815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      }
1771815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    }
17727537229470687560714401104558abdf82f81441Dirk Dougherty    // Pass full samplesList to SC to render the samples TOC to sampleNavTree hdf
1773da7497f52aae4ee0daff01cb2db0540dcb8e3faeDirk Dougherty    if (!offlineMode) {
1774815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      SampleCode.writeSamplesNavTree(samplesList, sampleGroupsRootNodes);
1775da7497f52aae4ee0daff01cb2db0540dcb8e3faeDirk Dougherty    }
17767537229470687560714401104558abdf82f81441Dirk Dougherty    // Iterate the samplecode projects writing the files to out
17777537229470687560714401104558abdf82f81441Dirk Dougherty    for (SampleCode sc : sampleCodes) {
17787537229470687560714401104558abdf82f81441Dirk Dougherty      sc.writeSamplesFiles(offlineMode);
17797537229470687560714401104558abdf82f81441Dirk Dougherty    }
17801b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  }
17811b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
17825ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  /**
17835ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  * Given an initial samples directory root, walk through the directory collecting
17845ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  * sample code project roots and adding them to an array of SampleCodes.
17855ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  * @param rootDir Root directory holding all browseable sample code projects,
17865ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  *        defined in frameworks/base/Android.mk as "-sampleDir path".
17875ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  */
17885ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  public static void getSampleProjects(File rootDir) {
17895ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty    for (File f : rootDir.listFiles()) {
17905ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty      String name = f.getName();
17915ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty      if (f.isDirectory()) {
17925ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty        if (isValidSampleProjectRoot(f)) {
17935ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty          sampleCodes.add(new SampleCode(f.getAbsolutePath(), "samples/" + name, name));
17945ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty        } else {
17955ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty          getSampleProjects(f);
17965ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty        }
17975ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty      }
17985ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty    }
17995ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  }
18005ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty
18015ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  /**
18025ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  * Test whether a given directory is the root directory for a sample code project.
1803e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini  * Root directories must contain a valid _index.jd file and a src/ directory
1804e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini  * or a module directory that contains a src/ directory.
18055ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  */
18065ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  public static boolean isValidSampleProjectRoot(File dir) {
1807e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini    File indexJd = new File(dir, "_index.jd");
1808e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini    if (!indexJd.exists()) {
1809e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini      return false;
1810e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini    }
1811e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini    File srcDir = new File(dir, "src");
1812e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini    if (srcDir.exists()) {
18135ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty      return true;
18145ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty    } else {
1815e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini      // Look for a src/ directory one level below the root directory, so
1816e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini      // modules are supported.
1817e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini      for (File childDir : dir.listFiles()) {
1818e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini        if (childDir.isDirectory()) {
1819e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini          srcDir = new File(childDir, "src");
1820e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini          if (srcDir.exists()) {
1821e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini            return true;
1822e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini          }
1823e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini        }
1824e11680d498d71b1503b77a5137bd67492dee0c58Renato Mangini      }
18255ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty      return false;
18265ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty    }
18275ce827a43e16b415ad8554c97cee01bf549067d6Dirk Dougherty  }
18285118ffe3bf77ec4efa070f36a7a62fd5d1bf16bfHui Shu
1829b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson  public static String getDocumentationStringForAnnotation(String annotationName) {
1830b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson    if (!documentAnnotations) return null;
1831b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson    if (annotationDocumentationMap == null) {
1832b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson      // parse the file for map
1833b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson      annotationDocumentationMap = new HashMap<String, String>();
1834b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson      try {
1835b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson        BufferedReader in = new BufferedReader(
1836b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson            new FileReader(documentAnnotationsPath));
1837b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson        try {
1838b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson          String line = in.readLine();
1839b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson          String[] split;
1840b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson          while (line != null) {
1841b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson            split = line.split(":");
1842b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson            annotationDocumentationMap.put(split[0], split[1]);
1843b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson            line = in.readLine();
1844b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson          }
1845b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson        } finally {
1846b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson          in.close();
1847b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson        }
1848b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson      } catch (IOException e) {
1849b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson        System.err.println("Unable to open annotations documentation file for reading: "
1850b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson            + documentAnnotationsPath);
1851b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson      }
1852b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson    }
1853b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson    return annotationDocumentationMap.get(annotationName);
1854b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson  }
1855b2a6c0413706468ba1dc6bcdd4e29d8eee20fffeJeff Arneson
1856920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
1857