196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectpackage jdiff;
296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectimport java.util.*;
496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectimport java.io.*;
596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project/**
796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * Emit HTML indexes which appear in the bottom left frame in the report.
896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * All indexes are links to JDiff-generated pages.
996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project *
1096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * See the file LICENSE.txt for copyright details.
1196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * @author Matthew Doar, mdoar@pobox.com
1296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project */
1396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectpublic class HTMLIndexes {
1496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
1596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Constructor. */
1696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public HTMLIndexes(HTMLReportGenerator h) {
1796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_ = h;
1896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
1996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
2096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The HTMLReportGenerator instance used to write HTML. */
2196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private HTMLReportGenerator h_ = null;
2296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
2396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit all the bottom left frame index files. */
2496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitAllBottomLeftFiles(String packagesIndexName,
2596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                       String classesIndexName,
2696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                       String constructorsIndexName,
2796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                       String methodsIndexName,
2896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                       String fieldsIndexName,
2996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                       String allDiffsIndexName,
3096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                       APIDiff apiDiff) {
3196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
3296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // indexType values: 0 = removals only, 1 = additions only,
3396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // 2 = changes only. 3 = all differences. Run all differences
3496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // first for all program element types so we know whether there
3596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // are any removals etc for the allDiffs index.
3696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitBottomLeftFile(packagesIndexName, apiDiff, 3, "Package");
3796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitBottomLeftFile(classesIndexName, apiDiff, 3, "Class");
3896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitBottomLeftFile(constructorsIndexName, apiDiff, 3, "Constructor");
3996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitBottomLeftFile(methodsIndexName, apiDiff, 3, "Method");
4096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitBottomLeftFile(fieldsIndexName, apiDiff, 3, "Field");
4196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // The allindex must be done last, since it uses the results from
4296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // the previous ones
4396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitBottomLeftFile(allDiffsIndexName, apiDiff, 3, "All");
4496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Now generate the other indexes
4596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        for (int indexType = 0; indexType < 3; indexType++) {
4696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitBottomLeftFile(packagesIndexName, apiDiff, indexType, "Package");
4796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitBottomLeftFile(classesIndexName, apiDiff, indexType, "Class");
4896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitBottomLeftFile(constructorsIndexName, apiDiff, indexType, "Constructor");
4996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitBottomLeftFile(methodsIndexName, apiDiff, indexType, "Method");
5096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitBottomLeftFile(fieldsIndexName, apiDiff, indexType, "Field");
5196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitBottomLeftFile(allDiffsIndexName, apiDiff, indexType, "All");
5296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
5396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (missingSincesFile != null)
5496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            missingSincesFile.close();
5596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
5696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
5796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
5896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit a single bottom left frame with the given kind of differences for
5996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * the given program element type in an alphabetical index.
6096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     *
6196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * @param indexBaseName The base name of the index file.
6296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * @param apiDiff The root element containing all the API differences.
6396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * @param indexType 0 = removals only, 1 = additions only,
6496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     *                  2 = changes only, 3 = all differences,
6596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * @param programElementType "Package", "Class", "Constructor",
6696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     *                           "Method", "Field" or "All".
6796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
6896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitBottomLeftFile(String indexBaseName,
6996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                   APIDiff apiDiff, int indexType,
7096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                   String programElementType) {
7196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String filename = indexBaseName;
7296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        try {
7396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String title = "Indexes";
7496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (indexType == 0) {
7596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                filename += "_removals" + h_.reportFileExt;
7696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                title = programElementType + " Removals Index";
7796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (indexType == 1) {
7896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                filename += "_additions" + h_.reportFileExt;
7996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                title = programElementType + " Additions Index";
8096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (indexType == 2) {
8196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                filename += "_changes" + h_.reportFileExt;
8296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                title = programElementType + " Changes Index";
8396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (indexType == 3) {
8496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                filename += "_all" + h_.reportFileExt;
8596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                title = programElementType + " Differences Index";
8696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
87e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty
8896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            FileOutputStream fos = new FileOutputStream(filename);
8996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.reportFile = new PrintWriter(fos);
9096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeStartHTMLHeader();
9196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeHTMLTitle(title);
9296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeStyleSheetRef();
9396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</HEAD>");
94e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            h_.writeText("<BODY class=\"gc-documentation\" style=\"padding:12px;\">");
95e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty
9696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (programElementType.compareTo("Package") == 0) {
9796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                emitPackagesIndex(apiDiff, indexType);
9896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (programElementType.compareTo("Class") == 0) {
9996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                emitClassesIndex(apiDiff, indexType);
10096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (programElementType.compareTo("Constructor") == 0) {
10196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                emitConstructorsIndex(apiDiff, indexType);
10296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (programElementType.compareTo("Method") == 0) {
10396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                emitMethodsIndex(apiDiff, indexType);
10496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (programElementType.compareTo("Field") == 0) {
10596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                emitFieldsIndex(apiDiff, indexType);
10696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (programElementType.compareTo("All") == 0) {
10796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                emitAllDiffsIndex(apiDiff, indexType);
10896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else{
10996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.out.println("Error: unknown program element type.");
11096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.exit(3);
11196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
11296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
11396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeHTMLFooter();
11496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.reportFile.close();
11596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } catch(IOException e) {
11696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            System.out.println("IO Error while attempting to create " + filename);
11796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            System.out.println("Error: " + e.getMessage());
11896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            System.exit(1);
11996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
12096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
12196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
12296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
12396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Generate a small header of letters which link to each section, but
12496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * do not emit a linked letter for the current section. Finish the list off
12596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * with a link to the top of the index.
12696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Caching the results of this function would save about 10s with large APIs.
12796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
12896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private void generateLetterIndex(List list, char currChar, boolean larger) {
12996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (larger)
13096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return; // Currently not using the larger functionality
13196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        int size = -2;
13296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project	if (larger)
13396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            size = -1;
13496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = null;
13596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (isAllNames)
13696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            iter = allNames.iterator();
13796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        else
13896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            iter = list.iterator();
13996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char oldsw = '\0';
14096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
14196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Index entry = (Index)(iter.next());
14296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            char sw = entry.name_.charAt(0);
14396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            char swu = Character.toUpperCase(sw);
14496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (swu != Character.toUpperCase(oldsw)) {
14596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                // Don't emit a reference to the current letter
14696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (Character.toUpperCase(sw) != Character.toUpperCase(currChar)) {
14796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    if (swu == '_') {
148e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty                        h_.writeText("<a href=\"#" + swu + "\"><font size=\"" + size + "\">" + "_" + "</font></a> ");
14996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    } else {
15096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        h_.writeText("<a href=\"#" + swu + "\"><font size=\"" + size + "\">" + swu + "</font></a> ");
15196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    }
15296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
15396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                oldsw = sw;
15496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
15596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
15696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText(" <a href=\"#topheader\"><font size=\"" + size + "\">TOP</font></a>");
15796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("<p><div style=\"line-height:1.5em;color:black\">");
15896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
15996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
16096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
16196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit a header for an index, including suitable links for removed,
16296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * added and changes sub-indexes.
16396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
16496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private void emitIndexHeader(String indexName, int indexType,
165e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty                                 boolean hasRemovals,
16696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                 boolean hasAdditions, boolean hasChanges) {
16796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String linkIndexName = indexName.toLowerCase();
16896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean isAllDiffs = false;
16996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (indexName.compareTo("All Differences") == 0) {
17096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            linkIndexName = "alldiffs";
17196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            isAllDiffs = true;
17296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
17396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("<a NAME=\"topheader\"></a>"); // Named anchor
174e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty        h_.writeText("<table summary=\"Index for " +  indexName + "\" width=\"100%\" class=\"jdiffIndex\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" style=\"padding-bottom:0;margin-bottom:0;\">");
17596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  <tr>");
17696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  <th class=\"indexHeader\">");
17796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("    Filter the Index:");
17896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  </th>");
17996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  </tr>");
18096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  <tr>");
181e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty        h_.writeText("  <td class=\"indexText\" style=\"line-height:1.3em;padding-left:2em;\">");
182e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty
18396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (indexType == 3) {
18496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project             h_.writeText("<b>" + indexName + "</b>"); }
18596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        else if (isAllDiffs) {
186e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            h_.writeText("<a href=\"" + linkIndexName + "_index_all" + h_.reportFileExt + "\" xclass=\"hiddenlink\">" + indexName + "</a>");
18796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
18896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        else {
18996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<a href=\"" + linkIndexName + "_index_all" + h_.reportFileExt + "\" class=\"staysblack\">All " + indexName + "</a>");
19096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
19196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
19296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  <br>");
193e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty
19496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasRemovals) {
19596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          if (indexType == 0) {
19696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<b>Removals</b>");
19796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          } else {
198e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            h_.writeText("<A HREF=\"" + linkIndexName + "_index_removals" + h_.reportFileExt + "\" xclass=\"hiddenlink\">Removals</A>");
19996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          }
20096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else {
20196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<font color=\"#999999\">Removals</font>");
20296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
20396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
20496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  <br>");
205e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty
20696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasAdditions) {
20796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          if (indexType == 1) {
20896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<b>Additions</b>");
20996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          } else {
210e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            h_.writeText("<A HREF=\"" + linkIndexName + "_index_additions" + h_.reportFileExt + "\"xclass=\"hiddenlink\">Additions</A>");
21196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          }
21296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else {
21396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<font color=\"#999999\">Additions</font>");
21496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
21596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
21696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  <br>");
217e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty
21896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasChanges) {
21996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          if (indexType == 2) {
22096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<b>Changes</b>");
22196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          } else {
222e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            h_.writeText("<A HREF=\"" + linkIndexName + "_index_changes" + h_.reportFileExt + "\"xclass=\"hiddenlink\">Changes</A>");
22396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          }
22496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else {
22596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<font color=\"#999999\">Changes</font>");
22696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
227e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty
22896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  </td>");
22996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  </tr>");
23096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("</table>");
231e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty        h_.writeText("<div id=\"indexTableCaption\" style=\"background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;\">");
232e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty        h_.writeText("Listed as: <span style=\"color:#069\"><strong>Added</strong></span>,  <span style=\"color:#069\"><strike>Removed</strike></span>,  <span style=\"color:#069\">Changed</span></font>");
233e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty        h_.writeText("</div>");
23496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
23596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
23696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
23796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit the index of packages, which appears in the bottom left frame. */
23896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitPackagesIndex(APIDiff apiDiff, int indexType) {
23996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the names of packages to a new list, to be sorted later
24096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        packageNames = new ArrayList(); // Index[]
24196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasRemovals = false;
24296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (apiDiff.packagesRemoved.size() != 0)
24396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            hasRemovals = true;
24496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasAdditions = false;
24596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (apiDiff.packagesAdded.size() != 0)
24696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            hasAdditions = true;
24796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasChanges = false;
24896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (apiDiff.packagesChanged.size() != 0)
24996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            hasChanges = true;
25096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        recordDiffs(hasRemovals, hasAdditions, hasChanges);
25196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = apiDiff.packagesRemoved.iterator();
25296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while ((indexType == 3 || indexType == 0) && iter.hasNext()) {
25396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageAPI pkg = (PackageAPI)(iter.next());
25496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            packageNames.add(new Index(pkg.name_, 0));
25596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
25696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        iter = apiDiff.packagesAdded.iterator();
25796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while ((indexType == 3 || indexType == 1) && iter.hasNext()) {
25896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageAPI pkg = (PackageAPI)(iter.next());
25996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            packageNames.add(new Index(pkg.name_, 1));
26096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
26196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        iter = apiDiff.packagesChanged.iterator();
26296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while ((indexType == 3 || indexType == 2) && iter.hasNext()) {
26396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageDiff pkg = (PackageDiff)(iter.next());
26496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            packageNames.add(new Index(pkg.name_, 2));
26596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
26696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(packageNames);
26796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
26896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // No letter index needed for packages
26996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
27096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Now emit all the package names and links to their respective files
27196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("Packages", indexType, hasRemovals, hasAdditions, hasChanges);
27296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
27396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Extra line because no index is emitted
27496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("<br>");
27596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
27696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Package names are unique, so no need to check for duplicates.
27796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        iter = packageNames.iterator();
27896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char oldsw = '\0';
279e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty        h_.writeText("<div id=\"indexTableEntries\">");
28096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
28196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Index pkg = (Index)(iter.next());
28296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            oldsw = emitPackageIndexEntry(pkg, oldsw);
28396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
28496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
28596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
286e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty    /**
287e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty     * Emit an index entry for a package.
28896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Package names are unique, so no need to check for duplicates.
28996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
29096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitPackageIndexEntry(Index pkg, char oldsw) {
29196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char res = oldsw;
29296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // See if we are in a new section of the alphabet
29396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char sw = pkg.name_.charAt(0);
29496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
29596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // No need to emit section letters for packages
29696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            res = sw;
29796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Add the named anchor for this new letter
29896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
29996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
30096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Package names are unique, so no need to check for duplicates.
30196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (pkg.changeType_ == 0) {
30296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A HREF=\"" + h_.reportFileName + "-summary" + h_.reportFileExt + "#" + pkg.name_  + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + pkg.name_ + "</strike></A><br>");
30396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (pkg.changeType_ == 1) {
30496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A HREF=\"" + h_.reportFileName + "-summary" + h_.reportFileExt + "#" + pkg.name_  + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + pkg.name_ + "</b></A><br>");
30596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (pkg.changeType_ == 2) {
30696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A HREF=\"pkg_" + pkg.name_ + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\">" + pkg.name_ + "</A><br>");
30796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
30896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return res;
30996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
31096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
31196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
31296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit all the entries and links for the given iterator
31396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * to their respective files.
31496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
31596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitIndexEntries(Iterator iter) {
31696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char oldsw = '\0';
31796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        int multipleMarker = 0;
31896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Index currIndex = null; // The entry which is emitted
31996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
32096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // The next entry after the current one
32196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Index nextIndex = (Index)(iter.next());
32296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (currIndex == null) {
32396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currIndex = nextIndex; // Prime the pump
32496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
32596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (nextIndex.name_.compareTo(currIndex.name_) == 0) {
32696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    // It's a duplicate index, so emit the name and then
32796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    // the indented entries
32896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    if (multipleMarker == 0)
32996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        multipleMarker = 1; // Start of a duplicate index
33096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    else if (multipleMarker == 1)
33196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        multipleMarker = 2; // Inside a duplicate index
33296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker);
33396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                } else {
33496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    if (multipleMarker == 1)
33596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        multipleMarker = 2; // Inside a duplicate index
33696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker);
33796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    multipleMarker = 0; // Not in a duplicate index any more
33896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
33996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currIndex = nextIndex;
34096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
34196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
34296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Emit the last entry left in currIndex
34396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1)
34496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            multipleMarker = 2; // Inside a duplicate index
34596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (currIndex != null)
34696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker);
34796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
34896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
34996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
35096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Whether to log all missing @since tags to a file or not.
35196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * If false, just warn the user.
35296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
35396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public static boolean logMissingSinces = true;
35496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
35596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The file used to output details of missing @since tags. */
35696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public static PrintWriter missingSincesFile = null;
35796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
35896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
35996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit elements in the given iterator which were added and
36096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * missing @since tags.
36196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
36296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitMissingSinces(Iterator iter) {
36396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//        if (!logMissingSinces)
36496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//            return;
36596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (missingSincesFile == null) {
36696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String sinceFileName = h_.outputDir + JDiff.DIR_SEP + "missingSinces.txt";
36796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            try {
36896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                FileOutputStream fos = new FileOutputStream(sinceFileName);
36996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                missingSincesFile = new PrintWriter(fos);
37096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } catch (IOException e) {
37196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.out.println("IO Error while attempting to create " + sinceFileName);
37296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.out.println("Error: " + e.getMessage());
37396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.exit(1);
37496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
37596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
37696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
37796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Index currIndex = (Index)(iter.next());
37896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Only display information about added elements
37996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (currIndex.changeType_ != 1)
38096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                continue;
38196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String programElementType = currIndex.ename_;
38296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String details = null;
38396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (programElementType.compareTo("class") == 0) {
38496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                details = currIndex.pkgName_ + "." + currIndex.name_;
38596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (currIndex.isInterface_)
38696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    details = details + " Interface";
38796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                else
38896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    details = details + " Class";
38996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (programElementType.compareTo("constructor") == 0) {
39096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                details = currIndex.pkgName_ + "." + currIndex.name_ + " Constructor (" + currIndex.type_ + ")";
39196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (programElementType.compareTo("method") == 0) {
39296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                details = currIndex.pkgName_ + "." + currIndex.className_ + " " + "Method " + currIndex.name_ + "(" + currIndex.type_ + ")";
39396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (programElementType.compareTo("field") == 0) {
39496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                details = currIndex.pkgName_ + "." + currIndex.className_ + " " + "Field " + currIndex.name_;
39596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
39696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.out.println("Error: unknown program element type");
39796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.exit(3);
39896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
39996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (currIndex.doc_ == null) {
40096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (logMissingSinces)
40196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    missingSincesFile.println("NO DOC BLOCK: " + details);
40296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                else
40396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    System.out.println("Warning: the doc block for the new element: " + details + " is missing, so there is no @since tag");
40496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (currIndex.doc_.indexOf("@since") != -1) {
40596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (logMissingSinces)
40696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    missingSincesFile.println("OK: " + details);
40796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
40896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (logMissingSinces)
40996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    missingSincesFile.println("MISSING @SINCE TAG: " + details);
41096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                else
41196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    System.out.println("Warning: the doc block for the new element: " + details + " is missing an @since tag");
41296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
41396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
41496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
41596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
41696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
41796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit a single entry and the link to its file.
41896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     *
41996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * @param programElementType "Class", "Constructor",
42096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     *                           "Method", or "Field".
42196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
42296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitIndexEntry(Index currIndex, char oldsw, int multipleMarker) {
42396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String programElementType = currIndex.ename_;
42496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (programElementType.compareTo("class") == 0) {
42596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitClassIndexEntry(currIndex, oldsw, multipleMarker);
42696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (programElementType.compareTo("constructor") == 0) {
42796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitCtorIndexEntry(currIndex, oldsw, multipleMarker);
42896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (programElementType.compareTo("method") == 0) {
42996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitMethodIndexEntry(currIndex, oldsw, multipleMarker);
43096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (programElementType.compareTo("field") == 0) {
43196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitFieldIndexEntry(currIndex, oldsw, multipleMarker);
43296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else {
43396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            System.out.println("Error: unknown program element type");
43496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            System.exit(3);
43596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
43696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return '\0';
43796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
43896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
43996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit the index of classes, which appears in the bottom left frame. */
44096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitClassesIndex(APIDiff apiDiff, int indexType) {
44196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the names of classes to a new list, to be sorted later
44296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        classNames = new ArrayList(); // Index[]
44396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasRemovals = false;
44496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasAdditions = false;
44596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasChanges = false;
44696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = apiDiff.packagesChanged.iterator();
44796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
44896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageDiff pkgDiff = (PackageDiff)(iter.next());
44996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (pkgDiff.classesRemoved.size() != 0)
45096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                hasRemovals = true;
45196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (pkgDiff.classesAdded.size() != 0)
45296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                hasAdditions = true;
45396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (pkgDiff.classesChanged.size() != 0)
45496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                hasChanges = true;
45596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            recordDiffs(hasRemovals, hasAdditions, hasChanges);
45696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String pkgName = pkgDiff.name_;
45796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Iterator iterClass = pkgDiff.classesRemoved.iterator();
45896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while ((indexType == 3 || indexType == 0) && iterClass.hasNext()) {
45996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassAPI cls = (ClassAPI)(iterClass.next());
46096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                classNames.add(new Index(cls.name_, 0, pkgName, cls.isInterface_));
46196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
46296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            iterClass = pkgDiff.classesAdded.iterator();
46396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while ((indexType == 3 || indexType == 1) && iterClass.hasNext()) {
46496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassAPI cls = (ClassAPI)(iterClass.next());
46596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                Index idx = new Index(cls.name_, 1, pkgName, cls.isInterface_);
46696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                idx.doc_ = cls.doc_; // Used for checking @since
46796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                classNames.add(idx);
46896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
46996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            iterClass = pkgDiff.classesChanged.iterator();
47096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while ((indexType == 3 || indexType == 2) && iterClass.hasNext()) {
47196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassDiff cls = (ClassDiff)(iterClass.next());
47296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                classNames.add(new Index(cls.name_, 2, pkgName, cls.isInterface_));
47396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
47496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
47596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(classNames);
47696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("Classes", indexType, hasRemovals, hasAdditions, hasChanges);
47796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexEntries(classNames.iterator());
47896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (indexType == 1)
47996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitMissingSinces(classNames.iterator());
48096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
48196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
48296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit an index entry for a class. */
48396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitClassIndexEntry(Index cls, char oldsw,
48496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                    int multipleMarker) {
48596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char res = oldsw;
48696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String className = cls.pkgName_ + "." + cls.name_;
48796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String classRef = cls.pkgName_ + "." + cls.name_;
48896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean isInterface = cls.isInterface_;
48996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // See if we are in a new section of the alphabet
49096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char sw = cls.name_.charAt(0);
49196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
49296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            res = sw;
49396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Add the named anchor for this new letter
49496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
49596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (sw == '_')
496e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty                h_.writeText("<br><b>_</b>&nbsp;");
49796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
49896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
49996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            generateLetterIndex(classNames, sw, false);
50096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
50196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with displaying duplicate indexes
50296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1) {
50396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<i>" + cls.name_ + "</i><br>");
50496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
50596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker != 0)
50696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.indent(INDENT_SIZE);
50796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (cls.changeType_ == 0) {
50896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Emit a reference to the correct place for the class in the
50996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // JDiff page for the package
51096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A HREF=\"pkg_" + cls.pkgName_ + h_.reportFileExt +
51196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                         "#" + cls.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + cls.name_ + "</strike></A><br>");
51296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (cls.changeType_ == 1) {
51396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String cn = cls.name_;
51496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker != 0)
51596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                cn = cls.pkgName_;
51696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (isInterface)
51796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<A HREF=\"pkg_" + cls.pkgName_ + h_.reportFileExt + "#" + cls.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><b><i>" + cn + "</i></b></A><br>");
51896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
51996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<A HREF=\"pkg_" + cls.pkgName_ + h_.reportFileExt + "#" + cls.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + cn + "</b></A><br>");
52096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (cls.changeType_ == 2) {
52196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String cn = cls.name_;
52296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker != 0)
52396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                cn = cls.pkgName_;
52496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (isInterface)
52596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<A HREF=\"" + classRef + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\"><i>" + cn + "</i></A><br>");
52696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
52796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<A HREF=\"" + classRef + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\">" + cn + "</A><br>");
52896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
52996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return res;
53096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
53196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
53296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
53396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit the index of all constructors, which appears in the bottom left
53496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * frame.
53596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
53696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitConstructorsIndex(APIDiff apiDiff, int indexType) {
53796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the names of constructors to a new list, to be sorted later
53896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ctorNames = new ArrayList(); // Index[]
53996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasRemovals = false;
54096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasAdditions = false;
54196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasChanges = false;
54296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = apiDiff.packagesChanged.iterator();
54396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
54496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageDiff pkgDiff = (PackageDiff)(iter.next());
54596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String pkgName = pkgDiff.name_;
54696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Iterator iterClass = pkgDiff.classesChanged.iterator();
54796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while (iterClass.hasNext()) {
54896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassDiff classDiff = (ClassDiff)(iterClass.next());
54996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.ctorsRemoved.size() != 0)
55096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasRemovals = true;
55196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.ctorsAdded.size() != 0)
55296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasAdditions = true;
55396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.ctorsChanged.size() != 0)
55496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasChanges = true;
55596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                recordDiffs(hasRemovals, hasAdditions, hasChanges);
55696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                String className = classDiff.name_;
55796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                Iterator iterCtor = classDiff.ctorsRemoved.iterator();
55896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 0) && iterCtor.hasNext()) {
55996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    ConstructorAPI ctor = (ConstructorAPI)(iterCtor.next());
5600860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young                    ctorNames.add(new Index(className, 0, pkgName, ctor.getSignature()));
56196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
56296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterCtor = classDiff.ctorsAdded.iterator();
56396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 1) && iterCtor.hasNext()) {
56496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    ConstructorAPI ctor = (ConstructorAPI)(iterCtor.next());
5650860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young                    Index idx = new Index(className, 1, pkgName, ctor.getSignature());
56696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    idx.doc_ = ctor.doc_; // Used for checking @since
56796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    ctorNames.add(idx);
56896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
56996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterCtor = classDiff.ctorsChanged.iterator();
57096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 2) && iterCtor.hasNext()) {
57196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    MemberDiff ctor = (MemberDiff)(iterCtor.next());
57296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    ctorNames.add(new Index(className, 2, pkgName, ctor.newType_));
57396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
57496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
57596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
57696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(ctorNames);
57796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("Constructors", indexType, hasRemovals, hasAdditions, hasChanges);
57896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexEntries(ctorNames.iterator());
57996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (indexType == 1)
58096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitMissingSinces(ctorNames.iterator());
58196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
58296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
58396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit an index entry for a constructor. */
58496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitCtorIndexEntry(Index ctor, char oldsw, int multipleMarker) {
58596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char res = oldsw;
58696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String className = ctor.pkgName_ + "." + ctor.name_;
58796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String memberRef = ctor.pkgName_ + "." + ctor.name_;
58896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String type = ctor.type_;
58996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (type.compareTo("void") == 0)
59096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            type = "";
59196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String shownType = HTMLReportGenerator.simpleName(type);
59296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // See if we are in a new section of the alphabet
59396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char sw = ctor.name_.charAt(0);
59496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
59596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            res = sw;
59696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Add the named anchor for this new letter
59796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
59896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (sw == '_')
599e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty                h_.writeText("<br><b>_</b>&nbsp;");
60096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
60196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
60296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            generateLetterIndex(ctorNames, sw, false);
60396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
60496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with displaying duplicate indexes
60596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1) {
60696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<i>" + ctor.name_ + "</i><br>");
60796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
60896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker != 0)
60996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.indent(INDENT_SIZE);
61096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with each type of difference
61196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // The output displayed for unique or duplicate entries is the same
61296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // for constructors.
61396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (ctor.changeType_ == 0) {
61496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + ".ctor_removed(" + type + ")";
61596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + ctor.name_ + "</strike>");
61696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.emitTypeWithParens(shownType, false);
61796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr>&nbsp;constructor<br>");
61896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (ctor.changeType_ == 1) {
61996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + ".ctor_added(" + type + ")";
62096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + ctor.name_ + "</b>");
62196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.emitTypeWithParens(shownType, false);
62296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr>&nbsp;constructor<br>");
62396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (ctor.changeType_ == 2) {
62496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + ".ctor_changed(" + type + ")";
62596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + ctor.name_);
62696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.emitTypeWithParens(shownType, false);
62796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr>&nbsp;constructor<br>");
62896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
62996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return res;
63096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
63196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
63296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
63396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit the index of all methods, which appears in the bottom left frame.
63496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
63596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitMethodsIndex(APIDiff apiDiff, int indexType) {
63696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the names of methods to a new list, to be sorted later
63796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        methNames = new ArrayList(); // Index[]
63896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasRemovals = false;
63996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasAdditions = false;
64096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasChanges = false;
64196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = apiDiff.packagesChanged.iterator();
64296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
64396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageDiff pkgDiff = (PackageDiff)(iter.next());
64496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String pkgName = pkgDiff.name_;
64596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Iterator iterClass = pkgDiff.classesChanged.iterator();
64696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while (iterClass.hasNext()) {
64796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassDiff classDiff = (ClassDiff)(iterClass.next());
64896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.methodsRemoved.size() != 0)
64996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasRemovals = true;
65096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.methodsAdded.size() != 0)
65196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasAdditions = true;
65296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.methodsChanged.size() != 0)
65396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasChanges = true;
65496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                recordDiffs(hasRemovals, hasAdditions, hasChanges);
65596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                String className = classDiff.name_;
65696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                Iterator iterMeth = classDiff.methodsRemoved.iterator();
65796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 0) && iterMeth.hasNext()) {
65896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    MethodAPI meth = (MethodAPI)(iterMeth.next());
65996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    methNames.add(new Index(meth.name_, 0, pkgName, className, meth.getSignature()));
66096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
66196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterMeth = classDiff.methodsAdded.iterator();
66296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 1) && iterMeth.hasNext()) {
66396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    MethodAPI meth = (MethodAPI)(iterMeth.next());
66496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    Index idx = new Index(meth.name_, 1, pkgName, className, meth.getSignature());
66596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    idx.doc_ = meth.doc_; // Used for checking @since
66696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    methNames.add(idx);
66796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
66896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterMeth = classDiff.methodsChanged.iterator();
66996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 2) && iterMeth.hasNext()) {
67096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    MemberDiff meth = (MemberDiff)(iterMeth.next());
67196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    methNames.add(new Index(meth.name_, 2, pkgName, className, meth.newSignature_));
67296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
67396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
67496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
67596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(methNames);
67696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("Methods", indexType, hasRemovals, hasAdditions, hasChanges);
67796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexEntries(methNames.iterator());
67896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (indexType == 1)
67996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitMissingSinces(methNames.iterator());
68096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
68196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
68296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit an index entry for a method. */
68396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitMethodIndexEntry(Index meth, char oldsw,
68496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                     int multipleMarker) {
68596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char res = oldsw;
68696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String className = meth.pkgName_ + "." + meth.className_;
68796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String memberRef = meth.pkgName_ + "." + meth.className_;
68896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String type = meth.type_;
68996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (type.compareTo("void") == 0)
69096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            type = "";
69196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String shownType = HTMLReportGenerator.simpleName(type);
69296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // See if we are in a new section of the alphabet
69396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char sw = meth.name_.charAt(0);
69496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
69596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            res = sw;
69696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Add the named anchor for this new letter
69796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
69896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (sw == '_')
699e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty                h_.writeText("<br><b>_</b>&nbsp;");
70096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
70196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
70296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            generateLetterIndex(methNames, sw, false);
70396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
70496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with displaying duplicate indexes
70596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1) {
70696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<i>" + meth.name_ + "</i><br>");
70796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
70896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker != 0)
70996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.indent(INDENT_SIZE);
71096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with each type of difference
71196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (meth.changeType_ == 0) {
71296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + "." + meth.name_ + "_removed(" + type + ")";
71396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker == 0) {
71496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + meth.name_ + "</strike>");
71596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
71696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
71796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;<strike>");
71896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
71996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</strike>&nbsp;in&nbsp;" + className);
72096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
72196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr><br>");
72296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (meth.changeType_ == 1) {
72396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + "." + meth.name_ + "_added(" + type + ")";
72496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker == 0) {
72596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + meth.name_ + "</b>");
72696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
72796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
72896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;<b>");
72996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
73096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</b>&nbsp;in&nbsp;" + className);
73196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
73296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr><br>");
73396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (meth.changeType_ == 2) {
73496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + "." + meth.name_ + "_changed(" + type + ")";
73596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker == 0) {
73696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + meth.name_);
73796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
73896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
73996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;");
74096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
74196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("&nbsp;in&nbsp;" + className);
74296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
74396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr><br>");
74496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
74596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return res;
74696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
74796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
74896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
74996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit the index of all fields, which appears in the bottom left frame.
75096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
75196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitFieldsIndex(APIDiff apiDiff, int indexType) {
75296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the names of fields to a new list, to be sorted later
75396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        fieldNames = new ArrayList(); // Index[]
75496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasRemovals = false;
75596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasAdditions = false;
75696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasChanges = false;
75796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = apiDiff.packagesChanged.iterator();
75896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
75996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageDiff pkgDiff = (PackageDiff)(iter.next());
76096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String pkgName = pkgDiff.name_;
76196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Iterator iterClass = pkgDiff.classesChanged.iterator();
76296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while (iterClass.hasNext()) {
76396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassDiff classDiff = (ClassDiff)(iterClass.next());
76496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.fieldsRemoved.size() != 0)
76596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasRemovals = true;
76696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.fieldsAdded.size() != 0)
76796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasAdditions = true;
76896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.fieldsChanged.size() != 0)
76996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasChanges = true;
77096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                recordDiffs(hasRemovals, hasAdditions, hasChanges);
77196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                String className = classDiff.name_;
77296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                Iterator iterField = classDiff.fieldsRemoved.iterator();
77396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 0) && iterField.hasNext()) {
77496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    FieldAPI fld = (FieldAPI)(iterField.next());
77596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    fieldNames.add(new Index(fld.name_, 0, pkgName, className, fld.type_, true));
77696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
77796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterField = classDiff.fieldsAdded.iterator();
77896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 1) && iterField.hasNext()) {
77996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    FieldAPI fld = (FieldAPI)(iterField.next());
78096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    Index idx = new Index(fld.name_, 1, pkgName, className, fld.type_, true);
78196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    idx.doc_ = fld.doc_; // Used for checking @since
78296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    fieldNames.add(idx);
78396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
78496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterField = classDiff.fieldsChanged.iterator();
78596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 2) && iterField.hasNext()) {
78696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    MemberDiff fld = (MemberDiff)(iterField.next());
78796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    fieldNames.add(new Index(fld.name_, 2, pkgName, className, fld.newType_, true));
78896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
78996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
79096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
79196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(fieldNames);
79296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("Fields", indexType, hasRemovals, hasAdditions, hasChanges);
79396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexEntries(fieldNames.iterator());
79496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (indexType == 1)
79596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitMissingSinces(fieldNames.iterator());
79696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
79796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
79896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit an index entry for a field. */
79996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitFieldIndexEntry(Index fld, char oldsw,
80096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                    int multipleMarker) {
80196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char res = oldsw;
80296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String className = fld.pkgName_ + "." + fld.className_;
80396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String memberRef = fld.pkgName_ + "." + fld.className_;
80496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String type = fld.type_;
80596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (type.compareTo("void") == 0)
80696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            type = "";
80796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String shownType = HTMLReportGenerator.simpleName(type);
80896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // See if we are in a new section of the alphabet
80996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char sw = fld.name_.charAt(0);
81096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
81196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            res = sw;
81296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Add the named anchor for this new letter
81396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
81496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (sw == '_')
815e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty                h_.writeText("<br><b>_</b>&nbsp;");
81696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
81796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
81896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            generateLetterIndex(fieldNames, sw, false);
81996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
82096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with displaying duplicate indexes
82196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1) {
82296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<i>" + fld.name_ + "</i><br>");
82396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
82496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker != 0) {
825e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            h_.writeText("<nobr>&nbsp;in&nbsp;");
82696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
82796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with each type of difference
82896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (fld.changeType_ == 0) {
829e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            String commentID = className + "." + fld.name_;
830e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            if (multipleMarker == 0) {
83196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + fld.name_ + "</strike></A>");
83296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
83396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
834e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty                h_.writeText("<A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + className + "</strike></A>");
83596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
83696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
83796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (fld.changeType_ == 1) {
838e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            String commentID = className + "." + fld.name_;
839e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            if (multipleMarker == 0) {
84096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + fld.name_ + "</A>");
84196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
84296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
843e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty                h_.writeText("<A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + className + "</A>");
84496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
84596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
84696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (fld.changeType_ == 2) {
847e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            String commentID = className + "." + fld.name_;
848e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty            if (multipleMarker == 0) {
84996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + fld.name_ + "</A>");
85096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
85196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
852e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty                h_.writeText("<A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + className + "</A>");
85396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
85496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
85596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
85696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return res;
85796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
85896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
859e064b57f77a1ccdb9541c5d4f16ef6bbed86eeb7Dirk Dougherty    /**
86096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit the index of all changes, which appears in the bottom left frame.
86196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Has to be run after all the other indexes have been written, since it
86296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * uses data from when they are generated.
86396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
86496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitAllDiffsIndex(APIDiff apiDiff, int indexType) {
86596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames = new ArrayList(); // Index[]
86696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the changes into one big list, and sort it by name,
86796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // ignoring case
86896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames.addAll(packageNames);
86996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames.addAll(classNames);
87096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames.addAll(ctorNames);
87196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames.addAll(methNames);
87296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames.addAll(fieldNames);
87396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Compares two Index objects' names, ignoring case differences.
87496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(allNames);
87596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
87696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("All Differences", indexType, atLeastOneRemoval,
87796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        atLeastOneAddition, atLeastOneChange);
87896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
87996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Tell generateLetterIndex to use allNames as the list when
88096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // using the other methods to generate the indexes.
88196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        isAllNames = true;
88296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
88396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Now emit a line for each entry in the list in the appropriate
88496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // format for each program element
88596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = allNames.iterator();
88696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char oldsw = '\0';
88796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        int multipleMarker = 0;
88896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Index currIndex = null; // The entry which is emitted
88996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
89096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // The next entry after the current one
89196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Index nextIndex = (Index)(iter.next());
89296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (currIndex == null) {
89396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currIndex = nextIndex; // Prime the pump
89496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
89596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (nextIndex.name_.compareTo(currIndex.name_) == 0) {
89696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    // It's a duplicate index, so emit the name and then
89796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    // the indented entries
89896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    if (multipleMarker == 0)
89996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        multipleMarker = 1; // Start of a duplicate index
90096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    else if (multipleMarker == 1)
90196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        multipleMarker = 2; // Inside a duplicate index
90296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
90396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                } else {
90496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    if (multipleMarker == 1)
90596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        multipleMarker = 2; // Inside a duplicate index
90696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
90796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    multipleMarker = 0; // Not in a duplicate index any more
90896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
90996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currIndex = nextIndex;
91096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
91196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
91296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Emit the last entry left in currIndex
91396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1)
91496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            multipleMarker = 2; // Inside a duplicate index
91596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (currIndex != null)
91696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
91796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
91896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Tell generateLetterIndex to stop using allNames as the list when
91996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // using the other methods to generate the indexes.
92096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        isAllNames = false;
92196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
92296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
92396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Call the appropriate *IndexEntry method for each entry. */
92496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitIndexEntryForAny(Index currIndex, char oldsw,
92596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                     int multipleMarker) {
92696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (currIndex.ename_.compareTo("package") == 0) {
92796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<!-- Package " + currIndex.name_ + " -->");
92896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitPackageIndexEntry(currIndex, oldsw);
92996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currIndex.ename_.compareTo("class") == 0) {
93096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<!-- Class " + currIndex.name_ + " -->");
93196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitClassIndexEntry(currIndex, oldsw, multipleMarker);
93296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currIndex.ename_.compareTo("constructor") == 0) {
93396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<!-- Constructor " + currIndex.name_ + " -->");
93496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitCtorIndexEntry(currIndex, oldsw, multipleMarker);
93596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currIndex.ename_.compareTo("method") == 0) {
93696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<!-- Method " + currIndex.name_ + " -->");
93796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitMethodIndexEntry(currIndex, oldsw, multipleMarker);
93896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currIndex.ename_.compareTo("field") == 0) {
93996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<!-- Field " + currIndex.name_ + " -->");
94096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitFieldIndexEntry(currIndex, oldsw, multipleMarker);
94196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
94296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return '\0';
94396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
94496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
94596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all changes for all program elements. */
94696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List allNames = null; // Index[]
94796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
94896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all package changes. */
94996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List packageNames = null; // Index[]
95096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
95196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all class changes. */
95296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List classNames = null; // Index[]
95396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
95496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all constructor changes. */
95596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List ctorNames = null; // Index[]
95696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
95796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all method changes. */
95896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List methNames = null; // Index[]
95996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
96096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all field changes. */
96196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List fieldNames = null; // Index[]
96296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
96396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** If set, then use allNames to generate the letter indexes. */
96496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private boolean isAllNames = false;
96596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
96696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
96796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * If any of the parameters are set, then set the respective atLeastOne
96896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * variable, used to generate the links at the top of the allDiffs index.
96996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Never unset an atLeastOne variable.
97096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
97196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private void recordDiffs(boolean hasRemovals, boolean hasAdditions,
97296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        boolean hasChanges) {
97396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasRemovals)
97496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            atLeastOneRemoval = true;
97596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasAdditions)
97696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            atLeastOneAddition = true;
97796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasChanges)
97896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            atLeastOneChange = true;
97996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
98096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
98196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Set if there was at least one removal in the entire API. */
98296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private boolean atLeastOneRemoval = false;
98396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
98496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Set if there was at least one addition in the entire API. */
98596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private boolean atLeastOneAddition = false;
98696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
98796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Set if there was at least one change in the entire API. */
98896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private boolean atLeastOneChange = false;
98996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
99096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
99196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * The number of non-breaking spaces to indent a duplicate indexes'
99296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * entries by.
99396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
99496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private final int INDENT_SIZE = 2;
99596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project}
99696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
99796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project/**
99896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * Class used to produce indexes of packages and classes.
99996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project *
100096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * See the file LICENSE.txt for copyright details.
100196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * @author Matthew Doar, mdoar@pobox.com
100296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project */
100396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectclass Index implements Comparable {
100496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
100596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The name of the program element this Index object represents. */
100696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String ename_ = null;
100796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
100896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Name of the changed package, class or member. */
100996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String name_ = null;
101096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
101196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Type of change. 0 = remove, 1 = add, 2 = change. */
101296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public int changeType_;
101396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
101496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Name of the changed package if name_ is a class name. */
101596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String pkgName_ = null;
101696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
101796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Set if this class is an interface. */
101896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public boolean isInterface_= false;
101996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
102096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The doc block of added elements, default is null. */
102196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String doc_ = null;
102296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
102396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
102496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * The new member type. For methods, this is the signature.
102596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
102696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String type_ = null;
102796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
102896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
102996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * The class name. Only used by methods.
103096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
103196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String className_ = null;
103296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
103396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Constructor for packages. */
103496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public Index(String name, int changeType) {
103596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ename_ = "package";
103696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        name_ = name;
103796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        changeType_ = changeType;
103896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
103996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
104096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Constructor for classes. */
104196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public Index(String name, int changeType, String pkgName, boolean isInterface) {
104296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ename_ = "class";
104396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        name_ = name;
104496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        changeType_ = changeType;
104596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        pkgName_ = pkgName;
104696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        isInterface_ = isInterface;
104796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
104896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
104996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Constructor for constructors. */
105096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public Index(String name, int changeType, String pkgName, String type) {
105196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ename_ = "constructor";
105296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        name_ = name;
105396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        changeType_ = changeType;
105496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        pkgName_ = pkgName;
105596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        type_  = type;
105696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
105796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
105896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Constructor for methods. */
105996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public Index(String name, int changeType, String pkgName,
106096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                 String className, String type) {
106196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ename_ = "method";
106296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        name_ = name;
106396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        changeType_ = changeType;
106496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        pkgName_ = pkgName;
106596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        className_ = className;
106696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        type_  = type;
106796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
106896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
106996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
107096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Constructor for fields.
107196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     *
107296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * The boolean <code>fld</code> is simply there to differentiate this
107396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * constructor from the one for methods.
107496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
107596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public Index(String name, int changeType, String pkgName,
107696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                 String className, String type, boolean fld) {
107796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ename_ = "field";
107896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        name_ = name;
107996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        changeType_ = changeType;
108096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        pkgName_ = pkgName;
108196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        className_ = className;
108296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        type_  = type;
108396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
108496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
108596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
108696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Compare two Index objects by their simple names, ignoring case. */
108796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public int compareTo(Object o) {
108896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return name_.compareToIgnoreCase(((Index)o).name_);
108996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
109096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
109196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project}
109296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
1093