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            }
8796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
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>");
9496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<BODY>");
9596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
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 == '_') {
14896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        h_.writeText("<a href=\"#" + swu + "\"><font size=\"" + size + "\">" + "underscore" + "</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,
16596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                 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
17496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("<table summary=\"Index for " +  indexName + "\" width=\"100%\" class=\"index\" border=\"0\" cellspacing=\"0\" cellpadding=\"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>");
18196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  <td class=\"indexText\" style=\"line-height:1.5em;padding-left:2em;\">");
18296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//        h_.writeText("  <div style=\"line-height:1.25em;padding-left:1em;>\">");
18396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//        h_.writeText("  <FONT SIZE=\"-1\">");
18496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // The index name is also a hidden link to the *index_all page
18596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (indexType == 3) {
18696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project             h_.writeText("<b>" + indexName + "</b>"); }
18796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        else if (isAllDiffs) {
18896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<a href=\"" + linkIndexName + "_index_all" + h_.reportFileExt + "\" class=\"hiddenlink\">" + indexName + "</a>");
18996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
19096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        else {
19196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<a href=\"" + linkIndexName + "_index_all" + h_.reportFileExt + "\" class=\"staysblack\">All " + indexName + "</a>");
19296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
19396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//        h_.writeText("  </FONT>");
19496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
19596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  <br>");
19696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//        h_.writeText("  <FONT SIZE=\"-1\">");
19796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasRemovals) {
19896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          if (indexType == 0) {
19996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<b>Removals</b>");
20096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          } else {
20196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A HREF=\"" + linkIndexName + "_index_removals" + h_.reportFileExt + "\" class=\"hiddenlink\">Removals</A>");
20296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          }
20396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else {
20496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<font color=\"#999999\">Removals</font>");
20596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
20696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//        h_.writeText("  </FONT>");
20796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
20896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  <br>");
20996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//      h_.writeText("  <FONT SIZE=\"-1\">");
21096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasAdditions) {
21196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          if (indexType == 1) {
21296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<b>Additions</b>");
21396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          } else {
21496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A HREF=\"" + linkIndexName + "_index_additions" + h_.reportFileExt + "\"class=\"hiddenlink\">Additions</A>");
21596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          }
21696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else {
21796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<font color=\"#999999\">Additions</font>");
21896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
21996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//        h_.writeText("  </FONT>");
22096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
22196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  <br>");
22296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//         h_.writeText("  <FONT SIZE=\"-1\">");
22396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasChanges) {
22496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          if (indexType == 2) {
22596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<b>Changes</b>");
22696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          } else {
22796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A HREF=\"" + linkIndexName + "_index_changes" + h_.reportFileExt + "\"class=\"hiddenlink\">Changes</A>");
22896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project          }
22996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else {
23096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<font color=\"#999999\">Changes</font>");
23196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
23296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//        h_.writeText("  </FONT>");
23396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//        h_.writeText("  </div>");
23496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  </td>");
23596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  </tr>");
23696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("</table>");
23796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("<font size=\"-2\"><strong>Bold</strong>&nbsp;indicates&nbsp;New;&nbsp;<strike>Strike</strike>&nbsp;indicates&nbsp;deleted</font>");
23896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("  </br>");
23996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
24096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
24196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
24296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit the index of packages, which appears in the bottom left frame. */
24396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitPackagesIndex(APIDiff apiDiff, int indexType) {
24496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the names of packages to a new list, to be sorted later
24596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        packageNames = new ArrayList(); // Index[]
24696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasRemovals = false;
24796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (apiDiff.packagesRemoved.size() != 0)
24896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            hasRemovals = true;
24996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasAdditions = false;
25096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (apiDiff.packagesAdded.size() != 0)
25196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            hasAdditions = true;
25296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasChanges = false;
25396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (apiDiff.packagesChanged.size() != 0)
25496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            hasChanges = true;
25596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        recordDiffs(hasRemovals, hasAdditions, hasChanges);
25696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = apiDiff.packagesRemoved.iterator();
25796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while ((indexType == 3 || indexType == 0) && iter.hasNext()) {
25896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageAPI pkg = (PackageAPI)(iter.next());
25996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            packageNames.add(new Index(pkg.name_, 0));
26096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
26196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        iter = apiDiff.packagesAdded.iterator();
26296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while ((indexType == 3 || indexType == 1) && iter.hasNext()) {
26396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageAPI pkg = (PackageAPI)(iter.next());
26496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            packageNames.add(new Index(pkg.name_, 1));
26596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
26696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        iter = apiDiff.packagesChanged.iterator();
26796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while ((indexType == 3 || indexType == 2) && iter.hasNext()) {
26896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageDiff pkg = (PackageDiff)(iter.next());
26996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            packageNames.add(new Index(pkg.name_, 2));
27096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
27196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(packageNames);
27296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
27396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // No letter index needed for packages
27496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
27596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Now emit all the package names and links to their respective files
27696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("Packages", indexType, hasRemovals, hasAdditions, hasChanges);
27796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
27896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Extra line because no index is emitted
27996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        h_.writeText("<br>");
28096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
28196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Package names are unique, so no need to check for duplicates.
28296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        iter = packageNames.iterator();
28396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char oldsw = '\0';
28496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
28596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Index pkg = (Index)(iter.next());
28696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            oldsw = emitPackageIndexEntry(pkg, oldsw);
28796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
28896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
28996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
29096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
29196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit an index entry for a package.
29296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Package names are unique, so no need to check for duplicates.
29396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
29496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitPackageIndexEntry(Index pkg, char oldsw) {
29596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char res = oldsw;
29696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // See if we are in a new section of the alphabet
29796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char sw = pkg.name_.charAt(0);
29896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
29996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // No need to emit section letters for packages
30096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            res = sw;
30196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Add the named anchor for this new letter
30296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
30396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
30496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Package names are unique, so no need to check for duplicates.
30596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (pkg.changeType_ == 0) {
30696b00fec6cd6068c1c5ae09de0358340c0ec499eThe 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>");
30796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (pkg.changeType_ == 1) {
30896b00fec6cd6068c1c5ae09de0358340c0ec499eThe 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>");
30996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (pkg.changeType_ == 2) {
31096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A HREF=\"pkg_" + pkg.name_ + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\">" + pkg.name_ + "</A><br>");
31196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
31296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return res;
31396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
31496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
31596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
31696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit all the entries and links for the given iterator
31796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * to their respective files.
31896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
31996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitIndexEntries(Iterator iter) {
32096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char oldsw = '\0';
32196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        int multipleMarker = 0;
32296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Index currIndex = null; // The entry which is emitted
32396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
32496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // The next entry after the current one
32596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Index nextIndex = (Index)(iter.next());
32696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (currIndex == null) {
32796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currIndex = nextIndex; // Prime the pump
32896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
32996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (nextIndex.name_.compareTo(currIndex.name_) == 0) {
33096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    // It's a duplicate index, so emit the name and then
33196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    // the indented entries
33296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    if (multipleMarker == 0)
33396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        multipleMarker = 1; // Start of a duplicate index
33496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    else 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                } else {
33896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    if (multipleMarker == 1)
33996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        multipleMarker = 2; // Inside a duplicate index
34096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker);
34196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    multipleMarker = 0; // Not in a duplicate index any more
34296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
34396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currIndex = nextIndex;
34496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
34596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
34696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Emit the last entry left in currIndex
34796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1)
34896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            multipleMarker = 2; // Inside a duplicate index
34996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (currIndex != null)
35096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker);
35196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
35296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
35396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
35496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Whether to log all missing @since tags to a file or not.
35596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * If false, just warn the user.
35696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
35796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public static boolean logMissingSinces = true;
35896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
35996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The file used to output details of missing @since tags. */
36096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public static PrintWriter missingSincesFile = null;
36196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
36296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
36396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit elements in the given iterator which were added and
36496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * missing @since tags.
36596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
36696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitMissingSinces(Iterator iter) {
36796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//        if (!logMissingSinces)
36896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project//            return;
36996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (missingSincesFile == null) {
37096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String sinceFileName = h_.outputDir + JDiff.DIR_SEP + "missingSinces.txt";
37196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            try {
37296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                FileOutputStream fos = new FileOutputStream(sinceFileName);
37396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                missingSincesFile = new PrintWriter(fos);
37496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } catch (IOException e) {
37596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.out.println("IO Error while attempting to create " + sinceFileName);
37696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.out.println("Error: " + e.getMessage());
37796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.exit(1);
37896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
37996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
38096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
38196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Index currIndex = (Index)(iter.next());
38296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Only display information about added elements
38396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (currIndex.changeType_ != 1)
38496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                continue;
38596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String programElementType = currIndex.ename_;
38696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String details = null;
38796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (programElementType.compareTo("class") == 0) {
38896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                details = currIndex.pkgName_ + "." + currIndex.name_;
38996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (currIndex.isInterface_)
39096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    details = details + " Interface";
39196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                else
39296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    details = details + " Class";
39396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (programElementType.compareTo("constructor") == 0) {
39496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                details = currIndex.pkgName_ + "." + currIndex.name_ + " Constructor (" + currIndex.type_ + ")";
39596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (programElementType.compareTo("method") == 0) {
39696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                details = currIndex.pkgName_ + "." + currIndex.className_ + " " + "Method " + currIndex.name_ + "(" + currIndex.type_ + ")";
39796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (programElementType.compareTo("field") == 0) {
39896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                details = currIndex.pkgName_ + "." + currIndex.className_ + " " + "Field " + currIndex.name_;
39996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
40096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.out.println("Error: unknown program element type");
40196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.exit(3);
40296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
40396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (currIndex.doc_ == null) {
40496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (logMissingSinces)
40596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    missingSincesFile.println("NO DOC BLOCK: " + details);
40696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                else
40796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    System.out.println("Warning: the doc block for the new element: " + details + " is missing, so there is no @since tag");
40896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else if (currIndex.doc_.indexOf("@since") != -1) {
40996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (logMissingSinces)
41096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    missingSincesFile.println("OK: " + details);
41196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
41296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (logMissingSinces)
41396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    missingSincesFile.println("MISSING @SINCE TAG: " + details);
41496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                else
41596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    System.out.println("Warning: the doc block for the new element: " + details + " is missing an @since tag");
41696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
41796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
41896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
41996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
42096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
42196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit a single entry and the link to its file.
42296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     *
42396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * @param programElementType "Class", "Constructor",
42496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     *                           "Method", or "Field".
42596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
42696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitIndexEntry(Index currIndex, char oldsw, int multipleMarker) {
42796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String programElementType = currIndex.ename_;
42896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (programElementType.compareTo("class") == 0) {
42996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitClassIndexEntry(currIndex, oldsw, multipleMarker);
43096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (programElementType.compareTo("constructor") == 0) {
43196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitCtorIndexEntry(currIndex, oldsw, multipleMarker);
43296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (programElementType.compareTo("method") == 0) {
43396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitMethodIndexEntry(currIndex, oldsw, multipleMarker);
43496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (programElementType.compareTo("field") == 0) {
43596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitFieldIndexEntry(currIndex, oldsw, multipleMarker);
43696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else {
43796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            System.out.println("Error: unknown program element type");
43896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            System.exit(3);
43996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
44096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return '\0';
44196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
44296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
44396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit the index of classes, which appears in the bottom left frame. */
44496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitClassesIndex(APIDiff apiDiff, int indexType) {
44596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the names of classes to a new list, to be sorted later
44696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        classNames = new ArrayList(); // Index[]
44796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasRemovals = false;
44896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasAdditions = false;
44996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasChanges = false;
45096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = apiDiff.packagesChanged.iterator();
45196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
45296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageDiff pkgDiff = (PackageDiff)(iter.next());
45396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (pkgDiff.classesRemoved.size() != 0)
45496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                hasRemovals = true;
45596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (pkgDiff.classesAdded.size() != 0)
45696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                hasAdditions = true;
45796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (pkgDiff.classesChanged.size() != 0)
45896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                hasChanges = true;
45996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            recordDiffs(hasRemovals, hasAdditions, hasChanges);
46096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String pkgName = pkgDiff.name_;
46196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Iterator iterClass = pkgDiff.classesRemoved.iterator();
46296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while ((indexType == 3 || indexType == 0) && iterClass.hasNext()) {
46396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassAPI cls = (ClassAPI)(iterClass.next());
46496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                classNames.add(new Index(cls.name_, 0, pkgName, cls.isInterface_));
46596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
46696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            iterClass = pkgDiff.classesAdded.iterator();
46796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while ((indexType == 3 || indexType == 1) && iterClass.hasNext()) {
46896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassAPI cls = (ClassAPI)(iterClass.next());
46996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                Index idx = new Index(cls.name_, 1, pkgName, cls.isInterface_);
47096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                idx.doc_ = cls.doc_; // Used for checking @since
47196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                classNames.add(idx);
47296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
47396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            iterClass = pkgDiff.classesChanged.iterator();
47496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while ((indexType == 3 || indexType == 2) && iterClass.hasNext()) {
47596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassDiff cls = (ClassDiff)(iterClass.next());
47696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                classNames.add(new Index(cls.name_, 2, pkgName, cls.isInterface_));
47796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
47896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
47996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(classNames);
48096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("Classes", indexType, hasRemovals, hasAdditions, hasChanges);
48196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexEntries(classNames.iterator());
48296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (indexType == 1)
48396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitMissingSinces(classNames.iterator());
48496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
48596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
48696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit an index entry for a class. */
48796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitClassIndexEntry(Index cls, char oldsw,
48896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                    int multipleMarker) {
48996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char res = oldsw;
49096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String className = cls.pkgName_ + "." + cls.name_;
49196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String classRef = cls.pkgName_ + "." + cls.name_;
49296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean isInterface = cls.isInterface_;
49396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // See if we are in a new section of the alphabet
49496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char sw = cls.name_.charAt(0);
49596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
49696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            res = sw;
49796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Add the named anchor for this new letter
49896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
49996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (sw == '_')
50096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><b>underscore</b>&nbsp;");
50196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
50296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
50396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            generateLetterIndex(classNames, sw, false);
50496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
50596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with displaying duplicate indexes
50696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1) {
50796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<i>" + cls.name_ + "</i><br>");
50896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
50996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker != 0)
51096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.indent(INDENT_SIZE);
51196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (cls.changeType_ == 0) {
51296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Emit a reference to the correct place for the class in the
51396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // JDiff page for the package
51496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A HREF=\"pkg_" + cls.pkgName_ + h_.reportFileExt +
51596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                         "#" + cls.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + cls.name_ + "</strike></A><br>");
51696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (cls.changeType_ == 1) {
51796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String cn = cls.name_;
51896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker != 0)
51996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                cn = cls.pkgName_;
52096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (isInterface)
52196b00fec6cd6068c1c5ae09de0358340c0ec499eThe 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>");
52296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
52396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<A HREF=\"pkg_" + cls.pkgName_ + h_.reportFileExt + "#" + cls.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + cn + "</b></A><br>");
52496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (cls.changeType_ == 2) {
52596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String cn = cls.name_;
52696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker != 0)
52796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                cn = cls.pkgName_;
52896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (isInterface)
52996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<A HREF=\"" + classRef + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\"><i>" + cn + "</i></A><br>");
53096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
53196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<A HREF=\"" + classRef + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\">" + cn + "</A><br>");
53296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
53396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return res;
53496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
53596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
53696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
53796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit the index of all constructors, which appears in the bottom left
53896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * frame.
53996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
54096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitConstructorsIndex(APIDiff apiDiff, int indexType) {
54196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the names of constructors to a new list, to be sorted later
54296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ctorNames = new ArrayList(); // Index[]
54396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasRemovals = false;
54496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasAdditions = false;
54596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasChanges = false;
54696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = apiDiff.packagesChanged.iterator();
54796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
54896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageDiff pkgDiff = (PackageDiff)(iter.next());
54996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String pkgName = pkgDiff.name_;
55096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Iterator iterClass = pkgDiff.classesChanged.iterator();
55196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while (iterClass.hasNext()) {
55296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassDiff classDiff = (ClassDiff)(iterClass.next());
55396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.ctorsRemoved.size() != 0)
55496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasRemovals = true;
55596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.ctorsAdded.size() != 0)
55696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasAdditions = true;
55796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.ctorsChanged.size() != 0)
55896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasChanges = true;
55996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                recordDiffs(hasRemovals, hasAdditions, hasChanges);
56096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                String className = classDiff.name_;
56196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                Iterator iterCtor = classDiff.ctorsRemoved.iterator();
56296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 0) && iterCtor.hasNext()) {
56396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    ConstructorAPI ctor = (ConstructorAPI)(iterCtor.next());
56496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    ctorNames.add(new Index(className, 0, pkgName, ctor.type_));
56596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
56696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterCtor = classDiff.ctorsAdded.iterator();
56796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 1) && iterCtor.hasNext()) {
56896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    ConstructorAPI ctor = (ConstructorAPI)(iterCtor.next());
56996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    Index idx = new Index(className, 1, pkgName, ctor.type_);
57096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    idx.doc_ = ctor.doc_; // Used for checking @since
57196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    ctorNames.add(idx);
57296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
57396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterCtor = classDiff.ctorsChanged.iterator();
57496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 2) && iterCtor.hasNext()) {
57596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    MemberDiff ctor = (MemberDiff)(iterCtor.next());
57696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    ctorNames.add(new Index(className, 2, pkgName, ctor.newType_));
57796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
57896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
57996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
58096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(ctorNames);
58196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("Constructors", indexType, hasRemovals, hasAdditions, hasChanges);
58296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexEntries(ctorNames.iterator());
58396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (indexType == 1)
58496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitMissingSinces(ctorNames.iterator());
58596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
58696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
58796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit an index entry for a constructor. */
58896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitCtorIndexEntry(Index ctor, char oldsw, int multipleMarker) {
58996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char res = oldsw;
59096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String className = ctor.pkgName_ + "." + ctor.name_;
59196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String memberRef = ctor.pkgName_ + "." + ctor.name_;
59296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String type = ctor.type_;
59396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (type.compareTo("void") == 0)
59496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            type = "";
59596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String shownType = HTMLReportGenerator.simpleName(type);
59696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // See if we are in a new section of the alphabet
59796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char sw = ctor.name_.charAt(0);
59896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
59996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            res = sw;
60096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Add the named anchor for this new letter
60196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
60296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (sw == '_')
60396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><b>underscore</b>&nbsp;");
60496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
60596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
60696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            generateLetterIndex(ctorNames, sw, false);
60796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
60896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with displaying duplicate indexes
60996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1) {
61096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<i>" + ctor.name_ + "</i><br>");
61196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
61296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker != 0)
61396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.indent(INDENT_SIZE);
61496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with each type of difference
61596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // The output displayed for unique or duplicate entries is the same
61696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // for constructors.
61796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (ctor.changeType_ == 0) {
61896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + ".ctor_removed(" + type + ")";
61996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + ctor.name_ + "</strike>");
62096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.emitTypeWithParens(shownType, false);
62196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr>&nbsp;constructor<br>");
62296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (ctor.changeType_ == 1) {
62396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + ".ctor_added(" + type + ")";
62496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + ctor.name_ + "</b>");
62596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.emitTypeWithParens(shownType, false);
62696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr>&nbsp;constructor<br>");
62796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (ctor.changeType_ == 2) {
62896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + ".ctor_changed(" + type + ")";
62996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + ctor.name_);
63096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.emitTypeWithParens(shownType, false);
63196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr>&nbsp;constructor<br>");
63296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
63396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return res;
63496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
63596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
63696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
63796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit the index of all methods, which appears in the bottom left frame.
63896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
63996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitMethodsIndex(APIDiff apiDiff, int indexType) {
64096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the names of methods to a new list, to be sorted later
64196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        methNames = new ArrayList(); // Index[]
64296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasRemovals = false;
64396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasAdditions = false;
64496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasChanges = false;
64596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = apiDiff.packagesChanged.iterator();
64696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
64796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageDiff pkgDiff = (PackageDiff)(iter.next());
64896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String pkgName = pkgDiff.name_;
64996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Iterator iterClass = pkgDiff.classesChanged.iterator();
65096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while (iterClass.hasNext()) {
65196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassDiff classDiff = (ClassDiff)(iterClass.next());
65296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.methodsRemoved.size() != 0)
65396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasRemovals = true;
65496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.methodsAdded.size() != 0)
65596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasAdditions = true;
65696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.methodsChanged.size() != 0)
65796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasChanges = true;
65896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                recordDiffs(hasRemovals, hasAdditions, hasChanges);
65996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                String className = classDiff.name_;
66096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                Iterator iterMeth = classDiff.methodsRemoved.iterator();
66196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 0) && iterMeth.hasNext()) {
66296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    MethodAPI meth = (MethodAPI)(iterMeth.next());
66396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    methNames.add(new Index(meth.name_, 0, pkgName, className, meth.getSignature()));
66496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
66596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterMeth = classDiff.methodsAdded.iterator();
66696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 1) && iterMeth.hasNext()) {
66796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    MethodAPI meth = (MethodAPI)(iterMeth.next());
66896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    Index idx = new Index(meth.name_, 1, pkgName, className, meth.getSignature());
66996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    idx.doc_ = meth.doc_; // Used for checking @since
67096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    methNames.add(idx);
67196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
67296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterMeth = classDiff.methodsChanged.iterator();
67396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 2) && iterMeth.hasNext()) {
67496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    MemberDiff meth = (MemberDiff)(iterMeth.next());
67596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    methNames.add(new Index(meth.name_, 2, pkgName, className, meth.newSignature_));
67696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
67796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
67896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
67996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(methNames);
68096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("Methods", indexType, hasRemovals, hasAdditions, hasChanges);
68196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexEntries(methNames.iterator());
68296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (indexType == 1)
68396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitMissingSinces(methNames.iterator());
68496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
68596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
68696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit an index entry for a method. */
68796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitMethodIndexEntry(Index meth, char oldsw,
68896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                     int multipleMarker) {
68996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char res = oldsw;
69096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String className = meth.pkgName_ + "." + meth.className_;
69196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String memberRef = meth.pkgName_ + "." + meth.className_;
69296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String type = meth.type_;
69396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (type.compareTo("void") == 0)
69496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            type = "";
69596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String shownType = HTMLReportGenerator.simpleName(type);
69696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // See if we are in a new section of the alphabet
69796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char sw = meth.name_.charAt(0);
69896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
69996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            res = sw;
70096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Add the named anchor for this new letter
70196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
70296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (sw == '_')
70396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><b>underscore</b>&nbsp;");
70496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
70596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
70696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            generateLetterIndex(methNames, sw, false);
70796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
70896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with displaying duplicate indexes
70996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1) {
71096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<i>" + meth.name_ + "</i><br>");
71196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
71296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker != 0)
71396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.indent(INDENT_SIZE);
71496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with each type of difference
71596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (meth.changeType_ == 0) {
71696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + "." + meth.name_ + "_removed(" + type + ")";
71796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker == 0) {
71896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + meth.name_ + "</strike>");
71996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
72096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
72196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;<strike>");
72296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
72396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</strike>&nbsp;in&nbsp;" + className);
72496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
72596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr><br>");
72696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (meth.changeType_ == 1) {
72796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + "." + meth.name_ + "_added(" + type + ")";
72896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker == 0) {
72996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + meth.name_ + "</b>");
73096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
73196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
73296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;<b>");
73396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
73496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</b>&nbsp;in&nbsp;" + className);
73596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
73696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr><br>");
73796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (meth.changeType_ == 2) {
73896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + "." + meth.name_ + "_changed(" + type + ")";
73996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker == 0) {
74096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + meth.name_);
74196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
74296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
74396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;");
74496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.emitTypeWithParens(shownType, false);
74596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("&nbsp;in&nbsp;" + className);
74696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
74796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("</A></nobr><br>");
74896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
74996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return res;
75096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
75196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
75296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
75396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit the index of all fields, which appears in the bottom left frame.
75496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
75596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitFieldsIndex(APIDiff apiDiff, int indexType) {
75696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the names of fields to a new list, to be sorted later
75796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        fieldNames = new ArrayList(); // Index[]
75896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasRemovals = false;
75996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasAdditions = false;
76096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        boolean hasChanges = false;
76196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = apiDiff.packagesChanged.iterator();
76296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
76396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            PackageDiff pkgDiff = (PackageDiff)(iter.next());
76496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String pkgName = pkgDiff.name_;
76596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Iterator iterClass = pkgDiff.classesChanged.iterator();
76696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            while (iterClass.hasNext()) {
76796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ClassDiff classDiff = (ClassDiff)(iterClass.next());
76896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.fieldsRemoved.size() != 0)
76996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasRemovals = true;
77096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.fieldsAdded.size() != 0)
77196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasAdditions = true;
77296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (classDiff.fieldsChanged.size() != 0)
77396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    hasChanges = true;
77496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                recordDiffs(hasRemovals, hasAdditions, hasChanges);
77596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                String className = classDiff.name_;
77696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                Iterator iterField = classDiff.fieldsRemoved.iterator();
77796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 0) && iterField.hasNext()) {
77896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    FieldAPI fld = (FieldAPI)(iterField.next());
77996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    fieldNames.add(new Index(fld.name_, 0, pkgName, className, fld.type_, true));
78096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
78196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterField = classDiff.fieldsAdded.iterator();
78296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 1) && iterField.hasNext()) {
78396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    FieldAPI fld = (FieldAPI)(iterField.next());
78496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    Index idx = new Index(fld.name_, 1, pkgName, className, fld.type_, true);
78596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    idx.doc_ = fld.doc_; // Used for checking @since
78696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    fieldNames.add(idx);
78796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
78896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                iterField = classDiff.fieldsChanged.iterator();
78996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                while ((indexType == 3 || indexType == 2) && iterField.hasNext()) {
79096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    MemberDiff fld = (MemberDiff)(iterField.next());
79196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    fieldNames.add(new Index(fld.name_, 2, pkgName, className, fld.newType_, true));
79296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
79396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
79496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
79596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(fieldNames);
79696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("Fields", indexType, hasRemovals, hasAdditions, hasChanges);
79796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexEntries(fieldNames.iterator());
79896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (indexType == 1)
79996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            emitMissingSinces(fieldNames.iterator());
80096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
80196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
80296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Emit an index entry for a field. */
80396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitFieldIndexEntry(Index fld, char oldsw,
80496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                    int multipleMarker) {
80596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char res = oldsw;
80696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String className = fld.pkgName_ + "." + fld.className_;
80796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String memberRef = fld.pkgName_ + "." + fld.className_;
80896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String type = fld.type_;
80996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (type.compareTo("void") == 0)
81096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            type = "";
81196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String shownType = HTMLReportGenerator.simpleName(type);
81296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // See if we are in a new section of the alphabet
81396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char sw = fld.name_.charAt(0);
81496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
81596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            res = sw;
81696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Add the named anchor for this new letter
81796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
81896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (sw == '_')
81996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><b>underscore</b>&nbsp;");
82096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
82196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
82296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            generateLetterIndex(fieldNames, sw, false);
82396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
82496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with displaying duplicate indexes
82596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1) {
82696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<i>" + fld.name_ + "</i><br>");
82796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
82896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker != 0) {
82996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project// More context than this is helpful here: h_.indent(INDENT_SIZE);
83096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("&nbsp;in&nbsp;");
83196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
83296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with each type of difference
83396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (fld.changeType_ == 0) {
83496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + "." + fld.name_;
83596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker == 0) {
83696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + fld.name_ + "</strike></A>");
83796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
83896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
83996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + className + "</strike></A>");
84096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
84196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
84296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (fld.changeType_ == 1) {
84396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + "." + fld.name_;
84496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker == 0) {
84596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + fld.name_ + "</A>");
84696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
84796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
84896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + className + "</A>");
84996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
85096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
85196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (fld.changeType_ == 2) {
85296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String commentID = className + "." + fld.name_;
85396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (multipleMarker == 0) {
85496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + fld.name_ + "</A>");
85596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
85696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
85796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + className + "</A>");
85896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                h_.writeText("</nobr><br>");
85996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
86096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
86196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return res;
86296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
86396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
86496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
86596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Emit the index of all changes, which appears in the bottom left frame.
86696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Has to be run after all the other indexes have been written, since it
86796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * uses data from when they are generated.
86896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
86996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void emitAllDiffsIndex(APIDiff apiDiff, int indexType) {
87096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames = new ArrayList(); // Index[]
87196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add all the changes into one big list, and sort it by name,
87296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // ignoring case
87396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames.addAll(packageNames);
87496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames.addAll(classNames);
87596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames.addAll(ctorNames);
87696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames.addAll(methNames);
87796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        allNames.addAll(fieldNames);
87896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Compares two Index objects' names, ignoring case differences.
87996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Collections.sort(allNames);
88096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
88196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        emitIndexHeader("All Differences", indexType, atLeastOneRemoval,
88296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        atLeastOneAddition, atLeastOneChange);
88396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
88496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Tell generateLetterIndex to use allNames as the list when
88596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // using the other methods to generate the indexes.
88696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        isAllNames = true;
88796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
88896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Now emit a line for each entry in the list in the appropriate
88996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // format for each program element
89096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Iterator iter = allNames.iterator();
89196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        char oldsw = '\0';
89296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        int multipleMarker = 0;
89396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Index currIndex = null; // The entry which is emitted
89496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        while (iter.hasNext()) {
89596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // The next entry after the current one
89696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            Index nextIndex = (Index)(iter.next());
89796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (currIndex == null) {
89896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currIndex = nextIndex; // Prime the pump
89996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
90096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                if (nextIndex.name_.compareTo(currIndex.name_) == 0) {
90196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    // It's a duplicate index, so emit the name and then
90296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    // the indented entries
90396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    if (multipleMarker == 0)
90496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        multipleMarker = 1; // Start of a duplicate index
90596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    else if (multipleMarker == 1)
90696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        multipleMarker = 2; // Inside a duplicate index
90796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
90896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                } else {
90996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    if (multipleMarker == 1)
91096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        multipleMarker = 2; // Inside a duplicate index
91196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
91296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                    multipleMarker = 0; // Not in a duplicate index any more
91396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                }
91496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currIndex = nextIndex;
91596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
91696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
91796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Emit the last entry left in currIndex
91896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (multipleMarker == 1)
91996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            multipleMarker = 2; // Inside a duplicate index
92096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (currIndex != null)
92196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
92296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
92396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Tell generateLetterIndex to stop using allNames as the list when
92496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // using the other methods to generate the indexes.
92596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        isAllNames = false;
92696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
92796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
92896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Call the appropriate *IndexEntry method for each entry. */
92996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public char emitIndexEntryForAny(Index currIndex, char oldsw,
93096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                     int multipleMarker) {
93196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (currIndex.ename_.compareTo("package") == 0) {
93296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<!-- Package " + currIndex.name_ + " -->");
93396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitPackageIndexEntry(currIndex, oldsw);
93496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currIndex.ename_.compareTo("class") == 0) {
93596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<!-- Class " + currIndex.name_ + " -->");
93696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitClassIndexEntry(currIndex, oldsw, multipleMarker);
93796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currIndex.ename_.compareTo("constructor") == 0) {
93896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<!-- Constructor " + currIndex.name_ + " -->");
93996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitCtorIndexEntry(currIndex, oldsw, multipleMarker);
94096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currIndex.ename_.compareTo("method") == 0) {
94196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<!-- Method " + currIndex.name_ + " -->");
94296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitMethodIndexEntry(currIndex, oldsw, multipleMarker);
94396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currIndex.ename_.compareTo("field") == 0) {
94496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            h_.writeText("<!-- Field " + currIndex.name_ + " -->");
94596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            return emitFieldIndexEntry(currIndex, oldsw, multipleMarker);
94696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
94796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return '\0';
94896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
94996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
95096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all changes for all program elements. */
95196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List allNames = null; // Index[]
95296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
95396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all package changes. */
95496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List packageNames = null; // Index[]
95596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
95696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all class changes. */
95796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List classNames = null; // Index[]
95896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
95996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all constructor changes. */
96096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List ctorNames = null; // Index[]
96196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
96296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all method changes. */
96396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List methNames = null; // Index[]
96496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
96596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The list of all field changes. */
96696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private List fieldNames = null; // Index[]
96796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
96896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** If set, then use allNames to generate the letter indexes. */
96996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private boolean isAllNames = false;
97096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
97196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
97296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * If any of the parameters are set, then set the respective atLeastOne
97396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * variable, used to generate the links at the top of the allDiffs index.
97496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Never unset an atLeastOne variable.
97596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
97696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private void recordDiffs(boolean hasRemovals, boolean hasAdditions,
97796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                        boolean hasChanges) {
97896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasRemovals)
97996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            atLeastOneRemoval = true;
98096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasAdditions)
98196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            atLeastOneAddition = true;
98296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (hasChanges)
98396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            atLeastOneChange = true;
98496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
98596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
98696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Set if there was at least one removal in the entire API. */
98796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private boolean atLeastOneRemoval = false;
98896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
98996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Set if there was at least one addition in the entire API. */
99096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private boolean atLeastOneAddition = false;
99196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
99296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Set if there was at least one change in the entire API. */
99396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private boolean atLeastOneChange = false;
99496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
99596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
99696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * The number of non-breaking spaces to indent a duplicate indexes'
99796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * entries by.
99896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
99996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private final int INDENT_SIZE = 2;
100096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project}
100196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
100296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project/**
100396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * Class used to produce indexes of packages and classes.
100496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project *
100596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * See the file LICENSE.txt for copyright details.
100696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * @author Matthew Doar, mdoar@pobox.com
100796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project */
100896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectclass Index implements Comparable {
100996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
101096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The name of the program element this Index object represents. */
101196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String ename_ = null;
101296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
101396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Name of the changed package, class or member. */
101496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String name_ = null;
101596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
101696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Type of change. 0 = remove, 1 = add, 2 = change. */
101796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public int changeType_;
101896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
101996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Name of the changed package if name_ is a class name. */
102096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String pkgName_ = null;
102196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
102296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Set if this class is an interface. */
102396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public boolean isInterface_= false;
102496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
102596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The doc block of added elements, default is null. */
102696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String doc_ = null;
102796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
102896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
102996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * The new member type. For methods, this is the signature.
103096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
103196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String type_ = null;
103296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
103396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
103496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * The class name. Only used by methods.
103596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
103696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public String className_ = null;
103796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
103896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Constructor for packages. */
103996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public Index(String name, int changeType) {
104096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ename_ = "package";
104196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        name_ = name;
104296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        changeType_ = changeType;
104396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
104496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
104596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Constructor for classes. */
104696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public Index(String name, int changeType, String pkgName, boolean isInterface) {
104796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ename_ = "class";
104896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        name_ = name;
104996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        changeType_ = changeType;
105096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        pkgName_ = pkgName;
105196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        isInterface_ = isInterface;
105296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
105396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
105496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Constructor for constructors. */
105596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public Index(String name, int changeType, String pkgName, String type) {
105696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ename_ = "constructor";
105796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        name_ = name;
105896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        changeType_ = changeType;
105996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        pkgName_ = pkgName;
106096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        type_  = type;
106196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
106296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
106396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Constructor for methods. */
106496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public Index(String name, int changeType, String pkgName,
106596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                 String className, String type) {
106696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ename_ = "method";
106796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        name_ = name;
106896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        changeType_ = changeType;
106996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        pkgName_ = pkgName;
107096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        className_ = className;
107196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        type_  = type;
107296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
107396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
107496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /**
107596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Constructor for fields.
107696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     *
107796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * The boolean <code>fld</code> is simply there to differentiate this
107896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * constructor from the one for methods.
107996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
108096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public Index(String name, int changeType, String pkgName,
108196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                 String className, String type, boolean fld) {
108296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        ename_ = "field";
108396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        name_ = name;
108496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        changeType_ = changeType;
108596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        pkgName_ = pkgName;
108696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        className_ = className;
108796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        type_  = type;
108896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
108996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
109096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
109196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Compare two Index objects by their simple names, ignoring case. */
109296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public int compareTo(Object o) {
109396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return name_.compareToIgnoreCase(((Index)o).name_);
109496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
109596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
109696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project}
109796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
1098