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
689b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static String outputPathBase = "/";
699b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static ArrayList<String> inputPathHtmlDirs = new ArrayList<String>();
709b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static ArrayList<String> inputPathHtmlDir2 = new ArrayList<String>();
719b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static String outputPathHtmlDirs;
729b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static String outputPathHtmlDir2;
739b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static final String devsiteRoot = "en/";
749b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static String javadocDir = "reference/";
75920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static String htmlExtension;
76920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
77920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static RootDoc root;
78920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static ArrayList<String[]> mHDFData = new ArrayList<String[]>();
79920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static Map<Character, String> escapeChars = new HashMap<Character, String>();
80920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static String title = "";
81920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static SinceTagger sinceTagger = new SinceTagger();
827a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato  public static HashSet<String> knownTags = new HashSet<String>();
83920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static FederationTagger federationTagger = new FederationTagger();
849b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static Set<String> showAnnotations = new HashSet<String>();
859b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty  public static boolean includeDefaultAssets = true;
869ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson  private static boolean generateDocs = true;
879ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson  private static boolean parseComments = false;
8818b25554072c36d4d9652523ec15e0c5306101ceChirag Shah  private static String yamlNavFile = null;
893c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main
90920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static JSilver jSilver = null;
91920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
925ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly  private static boolean gmsRef = false;
935ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly  private static boolean gcmRef = false;
9488c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly  private static boolean sac = false;
955ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly
96920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static boolean checkLevel(int level) {
97920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (showLevel & level) == level;
98920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
993c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main
100920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1019ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson   * Returns true if we should parse javadoc comments,
1029ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson   * reporting errors in the process.
103920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1049ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson  public static boolean parseComments() {
1059ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson    return generateDocs || parseComments;
106920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
107920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
108920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static boolean checkLevel(boolean pub, boolean prot, boolean pkgp, boolean priv,
109920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      boolean hidden) {
110920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int level = 0;
111920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (hidden && !checkLevel(SHOW_HIDDEN)) {
112920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return false;
113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
114920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (pub && checkLevel(SHOW_PUBLIC)) {
115920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return true;
116920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
117920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (prot && checkLevel(SHOW_PROTECTED)) {
118920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return true;
119920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
120920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (pkgp && checkLevel(SHOW_PACKAGE)) {
121920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return true;
122920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
123920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (priv && checkLevel(SHOW_PRIVATE)) {
124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return true;
125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return false;
127920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void main(String[] args) {
130920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    com.sun.tools.javadoc.Main.execute(args);
131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static boolean start(RootDoc r) {
134f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein    long startTime = System.nanoTime();
135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String keepListFile = null;
136970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton    String proguardFile = null;
137920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String proofreadFile = null;
138920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String todoFile = null;
139920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String sdkValuePath = null;
140920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<SampleCode> sampleCodes = new ArrayList<SampleCode>();
141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String stubsDir = null;
14241d8656cf17e04b25a058d0874e401654ea547b4Dirk Dougherty    // Create the dependency graph for the stubs  directory
143920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    boolean offlineMode = false;
144920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String apiFile = null;
145920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String debugStubsFile = "";
146920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    HashSet<String> stubPackages = null;
1477a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    ArrayList<String> knownTagsFiles = new ArrayList<String>();
148920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
149920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    root = r;
150920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
151920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String[][] options = r.options();
152920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String[] a : options) {
153920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (a[0].equals("-d")) {
1549b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        outputPathBase = outputPathHtmlDirs = ClearPage.outputDir = a[1];
155920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-templatedir")) {
156920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ClearPage.addTemplateDir(a[1]);
157920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-hdf")) {
158920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        mHDFData.add(new String[] {a[1], a[2]});
1597a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato      } else if (a[0].equals("-knowntags")) {
1607a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato        knownTagsFiles.add(a[1]);
161920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-toroot")) {
162920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ClearPage.toroot = a[1];
163920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-samplecode")) {
164920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        sampleCodes.add(new SampleCode(a[1], a[2], a[3]));
1659b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      //the destination output path for main htmldir
166920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-htmldir")) {
1679b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        inputPathHtmlDirs.add(a[1]);
1689b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        ClearPage.htmlDirs = inputPathHtmlDirs;
1699b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      //the destination output path for additional htmldir
1709b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      } else if (a[0].equals("-htmldir2")) {
1719b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty          if (a[2].equals("default")) {
1729b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty          inputPathHtmlDirs.add(a[1]);
1739b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        } else {
1749b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty          inputPathHtmlDir2.add(a[1]);
1759b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty          outputPathHtmlDir2 = a[2];
1769b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        }
177920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-title")) {
178920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        Doclava.title = a[1];
179920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-werror")) {
180920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        Errors.setWarningsAreErrors(true);
181920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-error") || a[0].equals("-warning") || a[0].equals("-hide")) {
182920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        try {
183920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          int level = -1;
184920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          if (a[0].equals("-error")) {
185920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            level = Errors.ERROR;
186920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          } else if (a[0].equals("-warning")) {
187920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            level = Errors.WARNING;
188920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          } else if (a[0].equals("-hide")) {
189920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            level = Errors.HIDDEN;
190920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
191920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Errors.setErrorLevel(Integer.parseInt(a[1]), level);
192920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        } catch (NumberFormatException e) {
193920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          // already printed below
194920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return false;
195920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
196920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-keeplist")) {
197920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        keepListFile = a[1];
1989b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      } else if (a[0].equals("-showAnnotation")) {
1999b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        showAnnotations.add(a[1]);
200970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton      } else if (a[0].equals("-proguard")) {
2015ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly        proguardFile = a[1];
202920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-proofread")) {
203920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        proofreadFile = a[1];
204920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-todo")) {
205920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        todoFile = a[1];
206920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-public")) {
207920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        showLevel = SHOW_PUBLIC;
208920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-protected")) {
209920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        showLevel = SHOW_PROTECTED;
210920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-package")) {
211920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        showLevel = SHOW_PACKAGE;
212920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-private")) {
213920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        showLevel = SHOW_PRIVATE;
214920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-hidden")) {
215920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        showLevel = SHOW_HIDDEN;
216920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-stubs")) {
217920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        stubsDir = a[1];
218920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-stubpackages")) {
219920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        stubPackages = new HashSet<String>();
220920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        for (String pkg : a[1].split(":")) {
221920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          stubPackages.add(pkg);
222920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
223920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-sdkvalues")) {
224920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        sdkValuePath = a[1];
225040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      } else if (a[0].equals("-api")) {
226920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        apiFile = a[1];
227920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-nodocs")) {
2289ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson        generateDocs = false;
229e65daec66ebdf02baa00c0ee403321fa304f7ad5Dirk Dougherty      } else if (a[0].equals("-nodefaultassets")) {
230e65daec66ebdf02baa00c0ee403321fa304f7ad5Dirk Dougherty        includeDefaultAssets = false;
2319ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson      } else if (a[0].equals("-parsecomments")) {
2329ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson        parseComments = true;
233920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-since")) {
234920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        sinceTagger.addVersion(a[1], a[2]);
235920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-offlinemode")) {
236920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        offlineMode = true;
237920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (a[0].equals("-federate")) {
238920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        try {
239920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          String name = a[1];
240920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          URL federationURL = new URL(a[2]);
2411e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton          federationTagger.addSiteUrl(name, federationURL);
242920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        } catch (MalformedURLException e) {
243920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          System.err.println("Could not parse URL for federation: " + a[1]);
244920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return false;
245920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
2461e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton      } else if (a[0].equals("-federationapi")) {
2471e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton        String name = a[1];
2481e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton        String file = a[2];
2491e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton        federationTagger.addSiteApi(name, file);
25018b25554072c36d4d9652523ec15e0c5306101ceChirag Shah      } else if (a[0].equals("-yaml")) {
25118b25554072c36d4d9652523ec15e0c5306101ceChirag Shah        yamlNavFile = a[1];
2529b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      } else if (a[0].equals("-devsite")) {
2539b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        // Don't copy the doclava assets to devsite output (ie use proj assets only)
2549b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        includeDefaultAssets = false;
2559b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        outputPathHtmlDirs = outputPathHtmlDirs + "/" + devsiteRoot;
256920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
257920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
258920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
2597a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    if (!readKnownTagsFiles(knownTags, knownTagsFiles)) {
2607a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato      return false;
2617a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    }
262920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
263920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Set up the data structures
264920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Converter.makeInfo(r);
265920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
2669ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson    if (generateDocs) {
267920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClearPage.addBundledTemplateDir("assets/customizations");
268920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClearPage.addBundledTemplateDir("assets/templates");
269920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
270920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      List<ResourceLoader> resourceLoaders = new ArrayList<ResourceLoader>();
271920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      List<String> templates = ClearPage.getTemplateDirs();
272920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (String tmpl : templates) {
273920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        resourceLoaders.add(new FileSystemResourceLoader(tmpl));
274920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
275920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
276920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      templates = ClearPage.getBundledTemplateDirs();
277920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (String tmpl : templates) {
278f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein          // TODO - remove commented line - it's here for debugging purposes
279f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein        //  resourceLoaders.add(new FileSystemResourceLoader("/Volumes/Android/master/external/doclava/res/" + tmpl));
280920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        resourceLoaders.add(new ClassResourceLoader(Doclava.class, '/'+tmpl));
281920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
282920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
283920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ResourceLoader compositeResourceLoader = new CompositeResourceLoader(resourceLoaders);
284920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      jSilver = new JSilver(compositeResourceLoader);
285920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
286920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (!Doclava.readTemplateSettings()) {
287920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return false;
288920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
289920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
290f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein      //startTime = System.nanoTime();
291920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
292920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Apply @since tags from the XML file
293920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sinceTagger.tagAll(Converter.rootClasses());
2943c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main
295920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Apply details of federated documentation
296920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      federationTagger.tagAll(Converter.rootClasses());
297920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
298920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Files for proofreading
299920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (proofreadFile != null) {
300920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        Proofread.initProofread(proofreadFile);
301920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
302920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (todoFile != null) {
303920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        TodoFile.writeTodoFile(todoFile);
304920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
305920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
3069b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      // HTML2 Pages -- Generate Pages from optional secondary dir
3079b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      if (!inputPathHtmlDir2.isEmpty()) {
3089b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        if (!outputPathHtmlDir2.isEmpty()) {
3099b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty          ClearPage.outputDir = outputPathBase + "/" + outputPathHtmlDir2;
3109b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        }
3119b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        ClearPage.htmlDirs = inputPathHtmlDir2;
3129b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        writeHTMLPages();
3139b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        ClearPage.htmlDirs = inputPathHtmlDirs;
3149b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      }
3159b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty
316920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // HTML Pages
3174bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      if (!ClearPage.htmlDirs.isEmpty()) {
3189b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        ClearPage.htmlDirs = inputPathHtmlDirs;
3199b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        ClearPage.outputDir = outputPathHtmlDirs;
320920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeHTMLPages();
321920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
322920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
323920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      writeAssets();
324920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
325920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Navigation tree
3265ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly       String refPrefix = new String();
3275ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      if(gmsRef){
3285ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly        refPrefix = "gms-";
3295ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      } else if(gcmRef){
3305ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly        refPrefix = "gcm-";
3315ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      }
3325ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      NavTree.writeNavTree(javadocDir, refPrefix);
333920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
33418b25554072c36d4d9652523ec15e0c5306101ceChirag Shah      // Write yaml tree.
33518b25554072c36d4d9652523ec15e0c5306101ceChirag Shah      if (yamlNavFile != null){
33618b25554072c36d4d9652523ec15e0c5306101ceChirag Shah        NavTree.writeYamlTree(javadocDir, yamlNavFile);
33718b25554072c36d4d9652523ec15e0c5306101ceChirag Shah      }
33818b25554072c36d4d9652523ec15e0c5306101ceChirag Shah
339920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Packages Pages
3405ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      writePackages(javadocDir + refPrefix + "packages" + htmlExtension);
341920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
342920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Classes
343920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      writeClassLists();
344920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      writeClasses();
345920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      writeHierarchy();
346920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // writeKeywords();
347920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
348920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Lists for JavaScript
349920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      writeLists();
350920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (keepListFile != null) {
351920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeKeepList(keepListFile);
352920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
353920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
354920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Sample Code
355920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (SampleCode sc : sampleCodes) {
356920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        sc.write(offlineMode);
357920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
358920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
359920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Index page
360920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      writeIndex();
361920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
362920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Proofread.finishProofread(proofreadFile);
363920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
364920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (sdkValuePath != null) {
365920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeSdkValues(sdkValuePath);
366920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
367920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
368920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
369920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Stubs
370970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton    if (stubsDir != null || apiFile != null || proguardFile != null) {
371970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton      Stubs.writeStubsAndApi(stubsDir, apiFile, proguardFile, stubPackages);
372920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
373920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
374920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Errors.printErrors();
3753c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main
376f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein    long time = System.nanoTime() - startTime;
377f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein    System.out.println("DroidDoc took " + (time / 1000000000) + " sec. to write docs to "
3789b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty        + outputPathBase );
379f959ed158599686910af990654d6c84d262868ffAndrew Sapperstein
380920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return !Errors.hadError;
381920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
382920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
383920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeIndex() {
384920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makeHDF();
385920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "index.cs", javadocDir + "index" + htmlExtension);
386920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
387920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
388920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static boolean readTemplateSettings() {
389920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makeHDF();
390920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
391920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // The .html extension is hard-coded in several .cs files,
392920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // and so you cannot currently set it as a property.
393920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    htmlExtension = ".html";
394920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // htmlExtension = data.getValue("template.extension", ".html");
395920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i = 0;
396920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    while (true) {
397920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String k = data.getValue("template.escape." + i + ".key", "");
398920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String v = data.getValue("template.escape." + i + ".value", "");
399920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if ("".equals(k)) {
400920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        break;
401920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
402920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (k.length() != 1) {
403920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        System.err.println("template.escape." + i + ".key must have a length of 1: " + k);
404920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return false;
405920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
406920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      escapeChars.put(k.charAt(0), v);
407920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      i++;
408920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
409920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return true;
410920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
411920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
4127a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    private static boolean readKnownTagsFiles(HashSet<String> knownTags,
4137a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato            ArrayList<String> knownTagsFiles) {
4147a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato        for (String fn: knownTagsFiles) {
4157a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato           BufferedReader in = null;
4167a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato           try {
4177a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               in = new BufferedReader(new FileReader(fn));
4187a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               int lineno = 0;
4197a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               boolean fail = false;
4207a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               while (true) {
4217a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   lineno++;
4227a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   String line = in.readLine();
4237a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   if (line == null) {
4247a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       break;
4257a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   }
4267a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   line = line.trim();
4277a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   if (line.length() == 0) {
4287a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       continue;
4297a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   } else if (line.charAt(0) == '#') {
4307a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       continue;
4317a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   }
4327a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   String[] words = line.split("\\s+", 2);
4337a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   if (words.length == 2) {
4347a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       if (words[1].charAt(0) != '#') {
4357a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                           System.err.println(fn + ":" + lineno
4367a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                                   + ": Only one tag allowed per line: " + line);
4377a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                           fail = true;
4387a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                           continue;
4397a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       }
4407a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   }
4417a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   knownTags.add(words[0]);
4427a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               }
4437a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               if (fail) {
4447a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   return false;
4457a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               }
4467a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato           } catch (IOException ex) {
4477a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               System.err.println("Error reading file: " + fn + " (" + ex.getMessage() + ")");
4487a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               return false;
4497a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato           } finally {
4507a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               if (in != null) {
4517a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   try {
4527a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                       in.close();
4537a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   } catch (IOException e) {
4547a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato                   }
4557a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato               }
4567a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato           }
4577a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato        }
4587a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato        return true;
4597a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    }
4607a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato
461920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static String escape(String s) {
462920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (escapeChars.size() == 0) {
463920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return s;
464920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
465920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    StringBuffer b = null;
466920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int begin = 0;
467920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    final int N = s.length();
468920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < N; i++) {
469920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      char c = s.charAt(i);
470920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String mapped = escapeChars.get(c);
471920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (mapped != null) {
472920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (b == null) {
473920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          b = new StringBuffer(s.length() + mapped.length());
474920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
475920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (begin != i) {
476920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          b.append(s.substring(begin, i));
477920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
478920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        b.append(mapped);
479920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        begin = i + 1;
480920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
481920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
482920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (b != null) {
483920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (begin != N) {
484920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        b.append(s.substring(begin, N));
485920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
486920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return b.toString();
487920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
488920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return s;
489920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
490920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
491920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void setPageTitle(Data data, String title) {
492920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String s = title;
493920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (Doclava.title.length() > 0) {
494920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      s += " - " + Doclava.title;
495920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
496920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue("page.title", s);
497920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
498920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
499920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
500920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static LanguageVersion languageVersion() {
501920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return LanguageVersion.JAVA_1_5;
502920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
503920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
504920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
505920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static int optionLength(String option) {
506920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-d")) {
507920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
508920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
509920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-templatedir")) {
510920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
511920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
512920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-hdf")) {
513920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 3;
514920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
5157a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    if (option.equals("-knowntags")) {
5167a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato      return 2;
5177a6456cec94b5d3107f36b61e9c9f303c68e9392Joe Onorato    }
518920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-toroot")) {
519920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
520920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
521920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-samplecode")) {
522920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 4;
523920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
524920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-htmldir")) {
525920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
526920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
5279b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    if (option.equals("-htmldir2")) {
5289b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      return 3;
5299b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    }
530920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-title")) {
531920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
532920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
533920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-werror")) {
534920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
535920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
536920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-hide")) {
537920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
538920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
539920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-warning")) {
540920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
541920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
542920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-error")) {
543920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
544920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
545920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-keeplist")) {
546920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
547920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
5489b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    if (option.equals("-showAnnotation")) {
5499b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      return 2;
5509b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    }
551970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton    if (option.equals("-proguard")) {
552970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton      return 2;
553970f13f08e404fa1e265e7ab24050f5a8c6e4603Jeff Hamilton    }
554920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-proofread")) {
555920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
556920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
557920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-todo")) {
558920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
559920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
560920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-public")) {
561920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
562920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
563920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-protected")) {
564920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
565920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
566920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-package")) {
567920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
568920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
569920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-private")) {
570920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
571920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
572920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-hidden")) {
573920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
574920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
575920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-stubs")) {
576920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
577920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
578920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-stubpackages")) {
579920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
580920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
581920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-sdkvalues")) {
582920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
583920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
584040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato    if (option.equals("-api")) {
585920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 2;
586920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
587920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-nodocs")) {
588920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
589920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
590e65daec66ebdf02baa00c0ee403321fa304f7ad5Dirk Dougherty    if (option.equals("-nodefaultassets")) {
591e65daec66ebdf02baa00c0ee403321fa304f7ad5Dirk Dougherty      return 1;
592e65daec66ebdf02baa00c0ee403321fa304f7ad5Dirk Dougherty    }
5939ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson    if (option.equals("-parsecomments")) {
5949ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson      return 1;
5959ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson    }
596920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-since")) {
597920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 3;
598920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
599920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-offlinemode")) {
600920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 1;
601920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
602920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (option.equals("-federate")) {
603920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return 3;
604920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
6051e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton    if (option.equals("-federationapi")) {
6061e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton      return 3;
6071e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton    }
60818b25554072c36d4d9652523ec15e0c5306101ceChirag Shah    if (option.equals("-yaml")) {
60918b25554072c36d4d9652523ec15e0c5306101ceChirag Shah      return 2;
61018b25554072c36d4d9652523ec15e0c5306101ceChirag Shah    }
6119b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    if (option.equals("-devsite")) {
6129b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty      return 1;
6139b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    }
6145ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly    if (option.equals("-gmsref")) {
6155ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      gmsRef = true;
6165ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      return 1;
6175ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly    }
6185ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly    if (option.equals("-gcmref")) {
6195ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      gcmRef = true;
6205ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      return 1;
6215ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly    }
622920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return 0;
623920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
624920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static boolean validOptions(String[][] options, DocErrorReporter r) {
625920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String[] a : options) {
626920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (a[0].equals("-error") || a[0].equals("-warning") || a[0].equals("-hide")) {
627920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        try {
628920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Integer.parseInt(a[1]);
629920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        } catch (NumberFormatException e) {
630920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          r.printError("bad -" + a[0] + " value must be a number: " + a[1]);
631920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return false;
632920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
633920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
634920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
635920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
636920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return true;
637920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
638920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
639920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static Data makeHDF() {
640920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = jSilver.createData();
641920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
642920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String[] p : mHDFData) {
643920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue(p[0], p[1]);
644920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
645920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
646920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return data;
647920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
648920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
649920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
650920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
651920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static Data makePackageHDF() {
652920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makeHDF();
653920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.rootClasses();
654920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
655920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    SortedMap<String, PackageInfo> sorted = new TreeMap<String, PackageInfo>();
656920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : classes) {
657920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      PackageInfo pkg = cl.containingPackage();
658920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String name;
659920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (pkg == null) {
660920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = "";
661920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
662920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = pkg.name();
663920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
664920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sorted.put(name, pkg);
665920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
666920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
667920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i = 0;
668920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String s : sorted.keySet()) {
669920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      PackageInfo pkg = sorted.get(s);
670920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
671920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (pkg.isHidden()) {
672920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        continue;
673920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
674920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Boolean allHidden = true;
675920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      int pass = 0;
676920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo[] classesToCheck = null;
677920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      while (pass < 5) {
678920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        switch (pass) {
679920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 0:
680920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.ordinaryClasses();
681920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
682920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 1:
683920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.enums();
684920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
685920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 2:
686920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.errors();
687920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
688920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 3:
689920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.exceptions();
690920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
691920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 4:
692920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.interfaces();
693920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
694920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          default:
695920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            System.err.println("Error reading package: " + pkg.name());
696920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
697920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
698920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        for (ClassInfo cl : classesToCheck) {
699920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          if (!cl.isHidden()) {
700920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            allHidden = false;
701920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
702920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
703920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
704920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (!allHidden) {
705920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          break;
706920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
707920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        pass++;
708920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
709920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (allHidden) {
710920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        continue;
711920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
7125ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      if(gmsRef){
7135ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly          data.setValue("reference.gms", "true");
7145ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      } else if(gcmRef){
7155ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly          data.setValue("reference.gcm", "true");
7165ab9cb535d77c7d83fabac028bbf13b2d27e0e63Robert Ly      }
717920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("reference", "1");
718920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("reference.apilevels", sinceTagger.hasVersions() ? "1" : "0");
719920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.packages." + i + ".name", s);
720920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.packages." + i + ".link", pkg.htmlPage());
721920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.packages." + i + ".since", pkg.getSince());
722920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      TagInfo.makeHDF(data, "docs.packages." + i + ".shortDescr", pkg.firstSentenceTags());
723920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      i++;
724920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
725920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
726920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    sinceTagger.writeVersionNames(data);
727920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return data;
728920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
729920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
730920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeDirectory(File dir, String relative, JSilver js) {
731920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    File[] files = dir.listFiles();
732920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i, count = files.length;
733920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (i = 0; i < count; i++) {
734920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      File f = files[i];
735920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (f.isFile()) {
736920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        String templ = relative + f.getName();
737920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        int len = templ.length();
738920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (len > 3 && ".cs".equals(templ.substring(len - 3))) {
739920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Data data = makeHDF();
740920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          String filename = templ.substring(0, len - 3) + htmlExtension;
741920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          ClearPage.write(data, templ, filename, js);
742920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        } else if (len > 3 && ".jd".equals(templ.substring(len - 3))) {
743920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          String filename = templ.substring(0, len - 3) + htmlExtension;
744920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          DocFile.writePage(f.getAbsolutePath(), relative, filename);
74588c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly        } else if(!f.getName().equals(".DS_Store")){
74688c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly              Data data = makeHDF();
74788c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly              String hdfValue = data.getValue("sac") == null ? "" : data.getValue("sac");
74888c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly              boolean allowExcepted = hdfValue.equals("true") ? true : false;
74988c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly              ClearPage.copyFile(allowExcepted, f, templ);
750920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
751920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (f.isDirectory()) {
752920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeDirectory(f, relative + f.getName() + "/", js);
753920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
754920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
755920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
756920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
757920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeHTMLPages() {
7584bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier    for (String htmlDir : ClearPage.htmlDirs) {
7594bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      File f = new File(htmlDir);
7604bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      if (!f.isDirectory()) {
7614bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier        System.err.println("htmlDir not a directory: " + htmlDir);
7624bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier        continue;
7634bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      }
764920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
7654bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      ResourceLoader loader = new FileSystemResourceLoader(f);
7664bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      JSilver js = new JSilver(loader);
7674bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier      writeDirectory(f, "", js);
7684bac50adef51d339bb967369f9aca0de7f6c1b2fBill Napier    }
769920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
770920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
771920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeAssets() {
772920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    JarFile thisJar = JarUtils.jarForClass(Doclava.class, null);
7739b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    if ((thisJar != null) && (includeDefaultAssets)) {
774920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
775920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        List<String> templateDirs = ClearPage.getBundledTemplateDirs();
776920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        for (String templateDir : templateDirs) {
777920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          String assetsDir = templateDir + "/assets";
778920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          JarUtils.copyResourcesToDirectory(thisJar, assetsDir, ClearPage.outputDir + "/assets");
779920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
780920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (IOException e) {
781920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        System.err.println("Error copying assets directory.");
782920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        e.printStackTrace();
783920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return;
784920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
785920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
786920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
7879b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    //write the project-specific assets
788920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    List<String> templateDirs = ClearPage.getTemplateDirs();
789920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String templateDir : templateDirs) {
790920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      File assets = new File(templateDir + "/assets");
791920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (assets.isDirectory()) {
792920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeDirectory(assets, "assets/", null);
793920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
794920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
7959b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty
7969b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    // Create the timestamp.js file based on .cs file
797460dd2aa33a4e4666eb05f7a26f335e2a012dbb7Scott Main    Data timedata = Doclava.makeHDF();
798460dd2aa33a4e4666eb05f7a26f335e2a012dbb7Scott Main    ClearPage.write(timedata, "timestamp.cs", "timestamp.js");
799920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
800920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
80171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  /** Go through the docs and generate meta-data about each
80271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      page to use in search suggestions */
803920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeLists() {
80471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
80571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    // Write the lists for API references
806920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makeHDF();
807920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
808920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.rootClasses();
809920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
810920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    SortedMap<String, Object> sorted = new TreeMap<String, Object>();
811920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : classes) {
812920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (cl.isHidden()) {
813920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        continue;
814920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
815920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sorted.put(cl.qualifiedName(), cl);
816920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      PackageInfo pkg = cl.containingPackage();
817920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String name;
818920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (pkg == null) {
819920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = "";
820920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
821920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = pkg.name();
822920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
823920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sorted.put(name, pkg);
824920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
825920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
826920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i = 0;
827920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String s : sorted.keySet()) {
828920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.pages." + i + ".id", "" + i);
829920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.pages." + i + ".label", s);
830920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
831920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Object o = sorted.get(s);
832920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (o instanceof PackageInfo) {
833920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        PackageInfo pkg = (PackageInfo) o;
834920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        data.setValue("docs.pages." + i + ".link", pkg.htmlPage());
835920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        data.setValue("docs.pages." + i + ".type", "package");
83668a238ae4243e6f0f2a370b8b915ef0686ca0b37Scott Main        data.setValue("docs.pages." + i + ".deprecated", pkg.isDeprecated() ? "true" : "false");
837920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (o instanceof ClassInfo) {
838920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ClassInfo cl = (ClassInfo) o;
839920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        data.setValue("docs.pages." + i + ".link", cl.htmlPage());
840920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        data.setValue("docs.pages." + i + ".type", "class");
84168a238ae4243e6f0f2a370b8b915ef0686ca0b37Scott Main        data.setValue("docs.pages." + i + ".deprecated", cl.isDeprecated() ? "true" : "false");
842920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
843920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      i++;
844920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
84557657b935a6aefc36b2a7f5704665e4da818c3e6Robert Ly    ClearPage.write(data, "lists.cs", javadocDir + "lists.js");
84671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
84771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
8487791802d9b43c2067b566bf81667096ed91decb8Scott Main    // Write the lists for JD documents (if there are HTML directories to process)
8497791802d9b43c2067b566bf81667096ed91decb8Scott Main    if (inputPathHtmlDirs.size() > 0) {
8507791802d9b43c2067b566bf81667096ed91decb8Scott Main      Data jddata = makeHDF();
8517791802d9b43c2067b566bf81667096ed91decb8Scott Main      Iterator counter = new Iterator();
8527791802d9b43c2067b566bf81667096ed91decb8Scott Main      for (String htmlDir : inputPathHtmlDirs) {
8537791802d9b43c2067b566bf81667096ed91decb8Scott Main        File dir = new File(htmlDir);
8547791802d9b43c2067b566bf81667096ed91decb8Scott Main        if (!dir.isDirectory()) {
8557791802d9b43c2067b566bf81667096ed91decb8Scott Main          continue;
8567791802d9b43c2067b566bf81667096ed91decb8Scott Main        }
8577791802d9b43c2067b566bf81667096ed91decb8Scott Main        writeJdDirList(dir, jddata, counter);
85871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      }
8597791802d9b43c2067b566bf81667096ed91decb8Scott Main      ClearPage.write(jddata, "jd_lists.cs", javadocDir + "jd_lists.js");
86071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    }
86171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  }
86271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
86371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  private static class Iterator {
86471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    int i = 0;
86571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  }
86671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
86771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  /** Write meta-data for a JD file, used for search suggestions */
86871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main  private static void writeJdDirList(File dir, Data data, Iterator counter) {
86971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    File[] files = dir.listFiles();
87071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    int i, count = files.length;
87171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    // Loop all files in given directory
87271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    for (i = 0; i < count; i++) {
87371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      File f = files[i];
87471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      if (f.isFile()) {
87571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        String filePath = f.getAbsolutePath();
87671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        String templ = f.getName();
87771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        int len = templ.length();
87871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        // If it's a .jd file we want to process
87971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        if (len > 3 && ".jd".equals(templ.substring(len - 3))) {
88071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          // remove the directories below the site root
88171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          String webPath = filePath.substring(filePath.indexOf("docs/html/") + 10, filePath.length());
88271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          // replace .jd with .html
88371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          webPath = webPath.substring(0, webPath.length() - 3) + htmlExtension;
88471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          // Parse the .jd file for properties data at top of page
88571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          Data hdf = Doclava.makeHDF();
88671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          String filedata = DocFile.readFile(filePath);
88771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          Matcher lines = DocFile.LINE.matcher(filedata);
88871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          String line = null;
88971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          // Get each line to add the key-value to hdf
89071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          while (lines.find()) {
89171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            line = lines.group(1);
89271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            if (line.length() > 0) {
89371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              // Stop when we hit the body
89471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              if (line.equals("@jd:body")) {
89571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                break;
89671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              }
89771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              Matcher prop = DocFile.PROP.matcher(line);
89871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              if (prop.matches()) {
89971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                String key = prop.group(1);
90071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                String value = prop.group(2);
90171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                hdf.setValue(key, value);
90271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              } else {
90371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                break;
90471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main              }
90571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            }
90671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          } // done gathering page properties
90771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
90871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          // Insert the goods into HDF data (title, link, tags, type)
90971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          String title = hdf.getValue("page.title", "");
9109950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main          title = title.replaceAll("\"", "'");
9119950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main          // if there's a <span> in the title, get rid of it
9129950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main          if (title.indexOf("<span") != -1) {
9139950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main            String[] splitTitle = title.split("<span(.*?)</span>");
9149950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main            title = splitTitle[0];
9159950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main            for (int j = 1; j < splitTitle.length; j++) {
9169950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main              title.concat(splitTitle[j]);
9179950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main            }
9189950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main          }
91971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          String tags = hdf.getValue("page.tags", "");
92071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          String dirName = (webPath.indexOf("/") != -1)
92171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main                  ? webPath.substring(0, webPath.indexOf("/")) : "";
92271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main
923489864e7dd2eee3f6a90919e5084964ad4d8b3c7Scott Main          if (!"".equals(title) &&
924489864e7dd2eee3f6a90919e5084964ad4d8b3c7Scott Main              !"intl".equals(dirName) &&
925489864e7dd2eee3f6a90919e5084964ad4d8b3c7Scott Main              !hdf.getBooleanValue("excludeFromSuggestions")) {
9269950dd094869cc176d63050a9e1ac3d0b4053f84Scott Main            data.setValue("docs.pages." + counter.i + ".label", title);
92771bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            data.setValue("docs.pages." + counter.i + ".link", webPath);
92871bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            data.setValue("docs.pages." + counter.i + ".tags", tags);
92971bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            data.setValue("docs.pages." + counter.i + ".type", dirName);
93071bf8d2ae787c28691910bb228a5d9efca9b153dScott Main            counter.i++;
93171bf8d2ae787c28691910bb228a5d9efca9b153dScott Main          }
93271bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        }
93371bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      } else if (f.isDirectory()) {
93471bf8d2ae787c28691910bb228a5d9efca9b153dScott Main        writeJdDirList(f, data, counter);
93571bf8d2ae787c28691910bb228a5d9efca9b153dScott Main      }
93671bf8d2ae787c28691910bb228a5d9efca9b153dScott Main    }
937920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
938920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
939920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void cantStripThis(ClassInfo cl, HashSet<ClassInfo> notStrippable) {
940920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (!notStrippable.add(cl)) {
941920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // slight optimization: if it already contains cl, it already contains
942920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // all of cl's parents
943920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return;
944920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
945920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo supr = cl.superclass();
946920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (supr != null) {
947920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      cantStripThis(supr, notStrippable);
948920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
949920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo iface : cl.interfaces()) {
950920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      cantStripThis(iface, notStrippable);
951920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
952920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
953920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
954920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static String getPrintableName(ClassInfo cl) {
955920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo containingClass = cl.containingClass();
956920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (containingClass != null) {
957920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // This is an inner class.
958920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String baseName = cl.name();
959920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      baseName = baseName.substring(baseName.lastIndexOf('.') + 1);
960920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return getPrintableName(containingClass) + '$' + baseName;
961920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
962920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return cl.qualifiedName();
963920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
964920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
965920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
966920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Writes the list of classes that must be present in order to provide the non-hidden APIs known
967920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * to javadoc.
9683c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
969920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param filename the path to the file to write the list to
970920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
971920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeKeepList(String filename) {
972920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    HashSet<ClassInfo> notStrippable = new HashSet<ClassInfo>();
973920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] all = Converter.allClasses();
974920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Arrays.sort(all); // just to make the file a little more readable
975920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
976920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // If a class is public and not hidden, then it and everything it derives
977920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // from cannot be stripped. Otherwise we can strip it.
978920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : all) {
979920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (cl.isPublic() && !cl.isHidden()) {
980920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        cantStripThis(cl, notStrippable);
981920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
982920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
983920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    PrintStream stream = null;
984920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    try {
985ed8f79791885c3ac15401d88a147aee551e1039eBrian Carlstrom      stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(filename)));
986920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (ClassInfo cl : notStrippable) {
987920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        stream.println(getPrintableName(cl));
988920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
989920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } catch (FileNotFoundException e) {
990920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      System.err.println("error writing file: " + filename);
991920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } finally {
992920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (stream != null) {
993920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        stream.close();
994920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
995920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
996920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
997920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
998920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static PackageInfo[] sVisiblePackages = null;
999920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1000920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static PackageInfo[] choosePackages() {
1001920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (sVisiblePackages != null) {
1002920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return sVisiblePackages;
1003920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1004920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1005920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.rootClasses();
1006920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    SortedMap<String, PackageInfo> sorted = new TreeMap<String, PackageInfo>();
1007920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : classes) {
1008920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      PackageInfo pkg = cl.containingPackage();
1009920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String name;
1010920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (pkg == null) {
1011920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = "";
1012920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
1013920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        name = pkg.name();
1014920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1015920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sorted.put(name, pkg);
1016920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1017920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1018920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<PackageInfo> result = new ArrayList<PackageInfo>();
1019920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1020920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String s : sorted.keySet()) {
1021920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      PackageInfo pkg = sorted.get(s);
1022920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1023920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (pkg.isHidden()) {
1024920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        continue;
1025920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1026920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Boolean allHidden = true;
1027920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      int pass = 0;
1028920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo[] classesToCheck = null;
1029920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      while (pass < 5) {
1030920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        switch (pass) {
1031920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 0:
1032920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.ordinaryClasses();
1033920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1034920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 1:
1035920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.enums();
1036920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1037920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 2:
1038920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.errors();
1039920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1040920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 3:
1041920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.exceptions();
1042920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1043920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          case 4:
1044920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            classesToCheck = pkg.interfaces();
1045920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1046920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          default:
1047920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            System.err.println("Error reading package: " + pkg.name());
1048920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1049920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1050920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        for (ClassInfo cl : classesToCheck) {
1051920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          if (!cl.isHidden()) {
1052920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            allHidden = false;
1053920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            break;
1054920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
1055920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1056920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (!allHidden) {
1057920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          break;
1058920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1059920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        pass++;
1060920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1061920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (allHidden) {
1062920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        continue;
1063920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1064920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1065920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      result.add(pkg);
1066920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1067920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1068920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    sVisiblePackages = result.toArray(new PackageInfo[result.size()]);
1069920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return sVisiblePackages;
1070920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1071920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1072920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writePackages(String filename) {
1073920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makePackageHDF();
1074920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1075920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i = 0;
1076920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (PackageInfo pkg : choosePackages()) {
1077920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      writePackage(pkg);
1078920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1079920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.packages." + i + ".name", pkg.name());
1080920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      data.setValue("docs.packages." + i + ".link", pkg.htmlPage());
1081920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      TagInfo.makeHDF(data, "docs.packages." + i + ".shortDescr", pkg.firstSentenceTags());
1082920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1083920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      i++;
1084920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1085920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1086920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    setPageTitle(data, "Package Index");
1087920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1088920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo.makeHDF(data, "root.descr", Converter.convertTags(root.inlineTags(), null));
1089920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1090920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "packages.cs", filename);
1091920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "package-list.cs", javadocDir + "package-list");
1092920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1093920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Proofread.writePackages(filename, Converter.convertTags(root.inlineTags(), null));
1094920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1095920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1096920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writePackage(PackageInfo pkg) {
1097920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // these this and the description are in the same directory,
1098920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // so it's okay
1099920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makePackageHDF();
1100920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1101920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String name = pkg.name();
1102920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1103920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue("package.name", name);
1104920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue("package.since", pkg.getSince());
1105920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue("package.descr", "...description...");
1106920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    pkg.setFederatedReferences(data, "package");
1107920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1108920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeClassListHDF(data, "package.interfaces", ClassInfo.sortByName(pkg.interfaces()));
1109920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeClassListHDF(data, "package.classes", ClassInfo.sortByName(pkg.ordinaryClasses()));
1110920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeClassListHDF(data, "package.enums", ClassInfo.sortByName(pkg.enums()));
1111920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeClassListHDF(data, "package.exceptions", ClassInfo.sortByName(pkg.exceptions()));
1112920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeClassListHDF(data, "package.errors", ClassInfo.sortByName(pkg.errors()));
1113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo.makeHDF(data, "package.shortDescr", pkg.firstSentenceTags());
1114920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo.makeHDF(data, "package.descr", pkg.inlineTags());
1115920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1116920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String filename = pkg.htmlPage();
1117920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    setPageTitle(data, name);
1118920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "package.cs", filename);
1119920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1120920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Proofread.writePackage(filename, pkg.inlineTags());
1121920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1122920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1123920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeClassLists() {
1124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i;
1125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makePackageHDF();
1126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1127920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = PackageInfo.filterHidden(Converter.convertClasses(root.classes()));
1128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (classes.length == 0) {
1129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return;
1130920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Sorter[] sorted = new Sorter[classes.length];
1133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (i = 0; i < sorted.length; i++) {
1134920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo cl = classes[i];
1135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String name = cl.name();
1136920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      sorted[i] = new Sorter(name, cl);
1137920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1138920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1139920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Arrays.sort(sorted);
1140920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // make a pass and resolve ones that have the same name
1142920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int firstMatch = 0;
1143920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String lastName = sorted[0].label;
1144920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (i = 1; i < sorted.length; i++) {
1145920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String s = sorted[i].label;
1146920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (!lastName.equals(s)) {
1147920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (firstMatch != i - 1) {
1148920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          // there were duplicates
1149920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          for (int j = firstMatch; j < i; j++) {
1150920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            PackageInfo pkg = ((ClassInfo) sorted[j].data).containingPackage();
1151920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            if (pkg != null) {
1152920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              sorted[j].label = sorted[j].label + " (" + pkg.name() + ")";
1153920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            }
1154920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
1155920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1156920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        firstMatch = i;
1157920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        lastName = s;
1158920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1159920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1160920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1161920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // and sort again
1162920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Arrays.sort(sorted);
1163920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1164920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (i = 0; i < sorted.length; i++) {
1165920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String s = sorted[i].label;
1166920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo cl = (ClassInfo) sorted[i].data;
1167920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      char first = Character.toUpperCase(s.charAt(0));
1168920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      cl.makeShortDescrHDF(data, "docs.classes." + first + '.' + i);
1169920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1170920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1171920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    setPageTitle(data, "Class Index");
1172920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "classes.cs", javadocDir + "classes" + htmlExtension);
1173920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1174920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1175920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  // we use the word keywords because "index" means something else in html land
1176920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  // the user only ever sees the word index
1177920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /*
1178920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * public static void writeKeywords() { ArrayList<KeywordEntry> keywords = new
1179920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * ArrayList<KeywordEntry>();
11803c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1181920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * ClassInfo[] classes = PackageInfo.filterHidden(Converter.convertClasses(root.classes()));
11823c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1183920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * for (ClassInfo cl: classes) { cl.makeKeywordEntries(keywords); }
11843c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1185920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * HDF data = makeHDF();
11863c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1187920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Collections.sort(keywords);
11883c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1189920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * int i=0; for (KeywordEntry entry: keywords) { String base = "keywords." + entry.firstChar() +
1190920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * "." + i; entry.makeHDF(data, base); i++; }
11913c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1192920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * setPageTitle(data, "Index"); ClearPage.write(data, "keywords.cs", javadocDir + "keywords" +
1193920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * htmlExtension); }
1194920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1195920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1196920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeHierarchy() {
1197920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.rootClasses();
1198920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> info = new ArrayList<ClassInfo>();
1199920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : classes) {
1200920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (!cl.isHidden()) {
1201920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        info.add(cl);
1202920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1203920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1204920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data data = makePackageHDF();
1205920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Hierarchy.makeHierarchy(data, info.toArray(new ClassInfo[info.size()]));
1206920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    setPageTitle(data, "Class Hierarchy");
1207920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(data, "hierarchy.cs", javadocDir + "hierarchy" + htmlExtension);
1208920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1209920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1210920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeClasses() {
1211920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.rootClasses();
1212920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1213920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : classes) {
1214920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Data data = makePackageHDF();
1215920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (!cl.isHidden()) {
1216920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeClass(cl, data);
1217920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1218920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1219920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1220920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1221920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void writeClass(ClassInfo cl, Data data) {
1222920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    cl.makeHDF(data);
1223920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    setPageTitle(data, cl.name());
12249b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    String outfile = cl.htmlPage();
12259b316c84e2e15268db79772d9cef60da1df488ecDirk Dougherty    ClearPage.write(data, "class.cs", outfile);
1226920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Proofread.writeClass(cl.htmlPage(), cl);
1227920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1228920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1229920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void makeClassListHDF(Data data, String base, ClassInfo[] classes) {
1230920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < classes.length; i++) {
1231920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo cl = classes[i];
1232920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (!cl.isHidden()) {
1233920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        cl.makeShortDescrHDF(data, base + "." + i);
1234920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1235920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1236920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1237920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1238920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static String linkTarget(String source, String target) {
1239920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String[] src = source.split("/");
1240920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String[] tgt = target.split("/");
1241920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1242920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int srclen = src.length;
1243920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int tgtlen = tgt.length;
1244920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1245920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int same = 0;
1246920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    while (same < (srclen - 1) && same < (tgtlen - 1) && (src[same].equals(tgt[same]))) {
1247920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      same++;
1248920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1249920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1250920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String s = "";
1251920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1252920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int up = srclen - same - 1;
1253920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < up; i++) {
1254920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      s += "../";
1255920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1256920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1257920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1258920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int N = tgtlen - 1;
1259920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = same; i < N; i++) {
1260920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      s += tgt[i] + '/';
1261920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1262920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    s += tgt[tgtlen - 1];
1263920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1264920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return s;
1265920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1266920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1267920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1268920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Returns true if the given element has an @hide or @pending annotation.
1269920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1270920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static boolean hasHideAnnotation(Doc doc) {
1271920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String comment = doc.getRawCommentText();
1272920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return comment.indexOf("@hide") != -1 || comment.indexOf("@pending") != -1;
1273920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1274920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1275920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1276920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Returns true if the given element is hidden.
1277920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1278920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static boolean isHidden(Doc doc) {
1279920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Methods, fields, constructors.
1280920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (doc instanceof MemberDoc) {
1281920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return hasHideAnnotation(doc);
1282920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1283920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1284920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Classes, interfaces, enums, annotation types.
1285920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (doc instanceof ClassDoc) {
1286920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassDoc classDoc = (ClassDoc) doc;
1287920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1288920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Check the containing package.
1289920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (hasHideAnnotation(classDoc.containingPackage())) {
1290920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return true;
1291920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1292920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1293920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Check the class doc and containing class docs if this is a
1294920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // nested class.
1295920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassDoc current = classDoc;
1296920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      do {
1297920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (hasHideAnnotation(current)) {
1298920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          return true;
1299920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1300920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1301920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        current = current.containingClass();
1302920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } while (current != null);
1303920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1304920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1305920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return false;
1306920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1307920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1308920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1309920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Filters out hidden elements.
1310920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1311920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static Object filterHidden(Object o, Class<?> expected) {
1312920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (o == null) {
1313920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return null;
1314920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1315920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1316920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Class type = o.getClass();
1317920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (type.getName().startsWith("com.sun.")) {
1318920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // TODO: Implement interfaces from superclasses, too.
1319920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return Proxy
1320920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          .newProxyInstance(type.getClassLoader(), type.getInterfaces(), new HideHandler(o));
1321920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else if (o instanceof Object[]) {
1322920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Class<?> componentType = expected.getComponentType();
1323920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Object[] array = (Object[]) o;
1324920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      List<Object> list = new ArrayList<Object>(array.length);
1325920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (Object entry : array) {
1326920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if ((entry instanceof Doc) && isHidden((Doc) entry)) {
1327920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          continue;
1328920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1329920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        list.add(filterHidden(entry, componentType));
1330920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1331920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return list.toArray((Object[]) Array.newInstance(componentType, list.size()));
1332920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else {
1333920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return o;
1334920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1335920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1336920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1337920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1338920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Filters hidden elements out of method return values.
1339920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1340920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static class HideHandler implements InvocationHandler {
1341920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1342920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    private final Object target;
1343920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1344920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    public HideHandler(Object target) {
1345920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      this.target = target;
1346920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1347920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1348920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
1349920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String methodName = method.getName();
1350920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (args != null) {
1351920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (methodName.equals("compareTo") || methodName.equals("equals")
1352920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            || methodName.equals("overrides") || methodName.equals("subclassOf")) {
1353920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          args[0] = unwrap(args[0]);
1354920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1355920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1356920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1357920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (methodName.equals("getRawCommentText")) {
1358920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return filterComment((String) method.invoke(target, args));
1359920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1360920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1361920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // escape "&" in disjunctive types.
1362920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (proxy instanceof Type && methodName.equals("toString")) {
1363920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return ((String) method.invoke(target, args)).replace("&", "&amp;");
1364920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1365920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1366920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
1367920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return filterHidden(method.invoke(target, args), method.getReturnType());
1368920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (InvocationTargetException e) {
1369920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        throw e.getTargetException();
1370920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1371920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1372920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1373920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    private String filterComment(String s) {
1374920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (s == null) {
1375920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return null;
1376920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1377920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1378920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      s = s.trim();
1379920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1380920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Work around off by one error
1381920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      while (s.length() >= 5 && s.charAt(s.length() - 5) == '{') {
1382920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        s += "&nbsp;";
1383920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1384920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1385920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return s;
1386920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1387920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1388920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    private static Object unwrap(Object proxy) {
1389920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (proxy instanceof Proxy) return ((HideHandler) Proxy.getInvocationHandler(proxy)).target;
1390920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return proxy;
1391920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1392920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1393920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1394920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1395920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Collect the values used by the Dev tools and write them in files packaged with the SDK
13963c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1397920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param output the ouput directory for the files.
1398920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1399920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeSdkValues(String output) {
1400920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<String> activityActions = new ArrayList<String>();
1401920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<String> broadcastActions = new ArrayList<String>();
1402920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<String> serviceActions = new ArrayList<String>();
1403920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<String> categories = new ArrayList<String>();
1404920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<String> features = new ArrayList<String>();
1405920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1406920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> layouts = new ArrayList<ClassInfo>();
1407920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> widgets = new ArrayList<ClassInfo>();
1408920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> layoutParams = new ArrayList<ClassInfo>();
1409920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1410920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] classes = Converter.allClasses();
1411920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1412920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Go through all the fields of all the classes, looking SDK stuff.
1413920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo clazz : classes) {
1414920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1415920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // first check constant fields for the SdkConstant annotation.
1416d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      ArrayList<FieldInfo> fields = clazz.allSelfFields();
1417920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (FieldInfo field : fields) {
1418920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        Object cValue = field.constantValue();
1419920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (cValue != null) {
1420d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            ArrayList<AnnotationInstanceInfo> annotations = field.annotations();
1421d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein          if (!annotations.isEmpty()) {
1422920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            for (AnnotationInstanceInfo annotation : annotations) {
1423920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              if (SDK_CONSTANT_ANNOTATION.equals(annotation.type().qualifiedName())) {
1424d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                if (!annotation.elementValues().isEmpty()) {
1425d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                  String type = annotation.elementValues().get(0).valueString();
1426920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  if (SDK_CONSTANT_TYPE_ACTIVITY_ACTION.equals(type)) {
1427920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                    activityActions.add(cValue.toString());
1428920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  } else if (SDK_CONSTANT_TYPE_BROADCAST_ACTION.equals(type)) {
1429920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                    broadcastActions.add(cValue.toString());
1430920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  } else if (SDK_CONSTANT_TYPE_SERVICE_ACTION.equals(type)) {
1431920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                    serviceActions.add(cValue.toString());
1432920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  } else if (SDK_CONSTANT_TYPE_CATEGORY.equals(type)) {
1433920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                    categories.add(cValue.toString());
1434920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  } else if (SDK_CONSTANT_TYPE_FEATURE.equals(type)) {
1435920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                    features.add(cValue.toString());
1436920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                  }
1437920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                }
1438920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                break;
1439920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              }
1440920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            }
1441920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
1442920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1443920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1444920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1445920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // Now check the class for @Widget or if its in the android.widget package
1446920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // (unless the class is hidden or abstract, or non public)
1447920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (clazz.isHidden() == false && clazz.isPublic() && clazz.isAbstract() == false) {
1448920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        boolean annotated = false;
1449d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        ArrayList<AnnotationInstanceInfo> annotations = clazz.annotations();
1450d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        if (!annotations.isEmpty()) {
1451920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          for (AnnotationInstanceInfo annotation : annotations) {
1452920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            if (SDK_WIDGET_ANNOTATION.equals(annotation.type().qualifiedName())) {
1453920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              widgets.add(clazz);
1454920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              annotated = true;
1455920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              break;
1456920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            } else if (SDK_LAYOUT_ANNOTATION.equals(annotation.type().qualifiedName())) {
1457920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              layouts.add(clazz);
1458920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              annotated = true;
1459920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              break;
1460920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            }
1461920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
1462920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1463920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1464920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (annotated == false) {
1465920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          // lets check if this is inside android.widget
1466920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          PackageInfo pckg = clazz.containingPackage();
1467920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          String packageName = pckg.name();
1468920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          if ("android.widget".equals(packageName) || "android.view".equals(packageName)) {
1469920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            // now we check what this class inherits either from android.view.ViewGroup
1470920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            // or android.view.View, or android.view.ViewGroup.LayoutParams
1471920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            int type = checkInheritance(clazz);
1472920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            switch (type) {
1473920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              case TYPE_WIDGET:
1474920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                widgets.add(clazz);
1475920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                break;
1476920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              case TYPE_LAYOUT:
1477920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                layouts.add(clazz);
1478920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                break;
1479920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              case TYPE_LAYOUT_PARAM:
1480920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                layoutParams.add(clazz);
1481920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                break;
1482920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            }
1483920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
1484920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
1485920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1486920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1487920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1488920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // now write the files, whether or not the list are empty.
1489920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // the SDK built requires those files to be present.
1490920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1491920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Collections.sort(activityActions);
1492920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeValues(output + "/activity_actions.txt", activityActions);
1493920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1494920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Collections.sort(broadcastActions);
1495920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeValues(output + "/broadcast_actions.txt", broadcastActions);
1496920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1497920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Collections.sort(serviceActions);
1498920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeValues(output + "/service_actions.txt", serviceActions);
1499920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1500920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Collections.sort(categories);
1501920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeValues(output + "/categories.txt", categories);
1502920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1503920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Collections.sort(features);
1504920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeValues(output + "/features.txt", features);
1505920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1506920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // before writing the list of classes, we do some checks, to make sure the layout params
1507920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // are enclosed by a layout class (and not one that has been declared as a widget)
1508920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < layoutParams.size();) {
1509920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo layoutParamClass = layoutParams.get(i);
1510920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo containingClass = layoutParamClass.containingClass();
1511920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (containingClass == null || layouts.indexOf(containingClass) == -1) {
1512920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        layoutParams.remove(i);
1513920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
1514920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        i++;
1515920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1516920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1517920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1518920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writeClasses(output + "/widgets.txt", widgets, layouts, layoutParams);
1519920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1520920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1521920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1522920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Writes a list of values into a text files.
15233c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1524920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param pathname the absolute os path of the output file.
1525920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param values the list of values to write.
1526920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1527920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeValues(String pathname, ArrayList<String> values) {
1528920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    FileWriter fw = null;
1529920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    BufferedWriter bw = null;
1530920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    try {
1531920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      fw = new FileWriter(pathname, false);
1532920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      bw = new BufferedWriter(fw);
1533920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1534920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (String value : values) {
1535920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        bw.append(value).append('\n');
1536920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1537920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } catch (IOException e) {
1538920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // pass for now
1539920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } finally {
1540920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
1541920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (bw != null) bw.close();
1542920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (IOException e) {
1543920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // pass for now
1544920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1545920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
1546920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (fw != null) fw.close();
1547920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (IOException e) {
1548920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // pass for now
1549920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1550920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1551920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1552920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1553920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1554920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Writes the widget/layout/layout param classes into a text files.
15553c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1556920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param pathname the absolute os path of the output file.
1557920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param widgets the list of widget classes to write.
1558920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param layouts the list of layout classes to write.
1559920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param layoutParams the list of layout param classes to write.
1560920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1561920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeClasses(String pathname, ArrayList<ClassInfo> widgets,
1562920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ArrayList<ClassInfo> layouts, ArrayList<ClassInfo> layoutParams) {
1563920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    FileWriter fw = null;
1564920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    BufferedWriter bw = null;
1565920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    try {
1566920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      fw = new FileWriter(pathname, false);
1567920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      bw = new BufferedWriter(fw);
1568920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1569920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // write the 3 types of classes.
1570920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (ClassInfo clazz : widgets) {
1571920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeClass(bw, clazz, 'W');
1572920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1573920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (ClassInfo clazz : layoutParams) {
1574920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeClass(bw, clazz, 'P');
1575920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1576920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (ClassInfo clazz : layouts) {
1577920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        writeClass(bw, clazz, 'L');
1578920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1579920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } catch (IOException e) {
1580920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // pass for now
1581920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } finally {
1582920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
1583920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (bw != null) bw.close();
1584920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (IOException e) {
1585920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // pass for now
1586920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1587920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      try {
1588920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (fw != null) fw.close();
1589920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } catch (IOException e) {
1590920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // pass for now
1591920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
1592920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1593920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1594920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1595920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1596920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Writes a class name and its super class names into a {@link BufferedWriter}.
15973c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1598920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param writer the BufferedWriter to write into
1599920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param clazz the class to write
1600920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param prefix the prefix to put at the beginning of the line.
1601920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @throws IOException
1602920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1603920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void writeClass(BufferedWriter writer, ClassInfo clazz, char prefix)
1604920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      throws IOException {
1605920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writer.append(prefix).append(clazz.qualifiedName());
1606920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo superClass = clazz;
1607920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    while ((superClass = superClass.superclass()) != null) {
1608920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      writer.append(' ').append(superClass.qualifiedName());
1609920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1610920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    writer.append('\n');
1611920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1612920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1613920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
1614920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Checks the inheritance of {@link ClassInfo} objects. This method return
1615920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <ul>
1616920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <li>{@link #TYPE_LAYOUT}: if the class extends <code>android.view.ViewGroup</code></li>
1617920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <li>{@link #TYPE_WIDGET}: if the class extends <code>android.view.View</code></li>
1618920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <li>{@link #TYPE_LAYOUT_PARAM}: if the class extends
1619920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <code>android.view.ViewGroup$LayoutParams</code></li>
1620920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * <li>{@link #TYPE_NONE}: in all other cases</li>
1621920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * </ul>
16223c1a6b2a6d80f02fa5460d9d8de356be5508de29Scott Main   *
1623920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * @param clazz the {@link ClassInfo} to check.
1624920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
1625920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static int checkInheritance(ClassInfo clazz) {
1626920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if ("android.view.ViewGroup".equals(clazz.qualifiedName())) {
1627920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return TYPE_LAYOUT;
1628920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else if ("android.view.View".equals(clazz.qualifiedName())) {
1629920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return TYPE_WIDGET;
1630920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else if ("android.view.ViewGroup.LayoutParams".equals(clazz.qualifiedName())) {
1631920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return TYPE_LAYOUT_PARAM;
1632920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1633920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1634920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo parent = clazz.superclass();
1635920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (parent != null) {
1636920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return checkInheritance(parent);
1637920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1638920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1639920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return TYPE_NONE;
1640920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
164118b25554072c36d4d9652523ec15e0c5306101ceChirag Shah
164218b25554072c36d4d9652523ec15e0c5306101ceChirag Shah  /**
164318b25554072c36d4d9652523ec15e0c5306101ceChirag Shah   * Ensures a trailing '/' at the end of a string.
164418b25554072c36d4d9652523ec15e0c5306101ceChirag Shah   */
164518b25554072c36d4d9652523ec15e0c5306101ceChirag Shah  static String ensureSlash(String path) {
164618b25554072c36d4d9652523ec15e0c5306101ceChirag Shah    return path.endsWith("/") ? path : path + "/";
164718b25554072c36d4d9652523ec15e0c5306101ceChirag Shah  }
1648920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
1649