| package jdiff; | |
| import java.util.*; | |
| import java.io.*; | |
| import java.text.*; | |
| /** | |
| * Emit an HTML file containing statistics about the differences. | |
| * Statistical information only appears if the -stats argument is used. | |
| * | |
| * See the file LICENSE.txt for copyright details. | |
| * @author Matthew Doar, mdoar@pobox.com | |
| */ | |
| public class HTMLStatistics { | |
| /** Constructor. */ | |
| public HTMLStatistics(HTMLReportGenerator h) { | |
| h_ = h; | |
| } | |
| /** The HTMLReportGenerator instance used to write HTML. */ | |
| private HTMLReportGenerator h_ = null; | |
| /** | |
| * Emit the statistics HTML file. | |
| */ | |
| public void emitStatistics(String filename, APIDiff apiDiff) { | |
| try { | |
| FileOutputStream fos = new FileOutputStream(filename); | |
| h_.reportFile = new PrintWriter(fos); | |
| // Write out the HTML header | |
| h_.writeStartHTMLHeader(); | |
| String oldAPIName = "Old API"; | |
| if (apiDiff.oldAPIName_ != null) | |
| oldAPIName = apiDiff.oldAPIName_; | |
| String newAPIName = "New API"; | |
| if (apiDiff.newAPIName_ != null) | |
| newAPIName = apiDiff.newAPIName_; | |
| // Write out the title | |
| h_.writeHTMLTitle("API Change Statistics"); | |
| h_.writeStyleSheetRef(); | |
| h_.writeText("</HEAD>"); | |
| h_.writeText("<body class=\"gc-documentation\">"); | |
| // writeText("<div class=\"g-section g-tpl-180\">"); | |
| // Add the nav bar for the summary page | |
| // Write a customized navigation bar for the statistics page | |
| h_.writeText("<!-- Start of nav bar -->"); | |
| SimpleDateFormat formatter | |
| = new SimpleDateFormat ("yyyy.MM.dd HH:mm"); | |
| Date day = new Date(); | |
| h_.writeText("<a name=\"top\"></a>"); | |
| h_.writeText("<div id=\"header\" style=\"margin-bottom:0;xborder-bottom:none;\">"); | |
| h_.writeText("<div id=\"headerLeft\">"); | |
| h_.writeText("<a href=\"../../../../index.html\" tabindex=\"-1\" target=\"_top\"><img src=\"../../../../assets/images/bg_logo.png\" alt=\"Android Developers\" /></a>"); | |
| h_.writeText("</div>"); | |
| h_.writeText(" <div id=\"headerRight\">"); | |
| h_.writeText(" <div id=\"headerLinks\">"); | |
| h_.writeText("<!-- <img src=\"/assets/images/icon_world.jpg\" alt=\"\" /> -->"); | |
| h_.writeText("<span class=\"text\">"); | |
| h_.writeText("<!-- <a href=\"#\">English</a> | -->"); | |
| h_.writeText("<nobr><a href=\"https://developer.android.com\" target=\"_top\">Android Developers</a> | <a href=\"https://www.android.com\" target=\"_top\">Android.com</a></nobr>"); | |
| h_.writeText("</span>"); | |
| h_.writeText("</div>"); | |
| h_.writeText(" <div class=\"and-diff-id\" style=\"margin-top:6px;margin-right:8px;\">"); | |
| h_.writeText(" <table class=\"diffspectable\">"); | |
| h_.writeText(" <tr>"); | |
| h_.writeText(" <td colspan=\"2\" class=\"diffspechead\">API Diff Specification</td>"); | |
| h_.writeText(" </tr>"); | |
| h_.writeText(" <tr>"); | |
| h_.writeText(" <td class=\"diffspec\" style=\"padding-top:.25em\">To Level:</td>"); | |
| h_.writeText(" <td class=\"diffvaluenew\" style=\"padding-top:.25em\">" + newAPIName + "</td>"); | |
| h_.writeText(" </tr>"); | |
| h_.writeText(" <tr>"); | |
| h_.writeText(" <td class=\"diffspec\">From Level:</td>"); | |
| h_.writeText(" <td class=\"diffvalueold\">" + oldAPIName + "</td>"); | |
| h_.writeText(" </tr>"); | |
| h_.writeText(" <tr>"); | |
| h_.writeText(" <td class=\"diffspec\">Generated</td>"); | |
| h_.writeText(" <td class=\"diffvalue\">" + formatter.format( day ) + "</td>"); | |
| h_.writeText(" </tr>"); | |
| h_.writeText(" </table>"); | |
| h_.writeText(" </div><!-- End and-diff-id -->"); | |
| h_.writeText(" <div class=\"and-diff-id\" style=\"margin-right:8px;\">"); | |
| h_.writeText(" <table class=\"diffspectable\">"); | |
| h_.writeText(" <tr>"); | |
| h_.writeText(" <td class=\"diffspec\" colspan=\"2\"><a href=\"../changes.html\" target=\"_top\">Top of Report</a>"); | |
| h_.writeText(" </tr>"); | |
| h_.writeText(" </table>"); | |
| h_.writeText(" </div> <!-- End and-diff-id -->"); | |
| h_.writeText(" </div> <!-- End headerRight -->"); | |
| h_.writeText(" </div> <!-- End header -->"); | |
| h_.writeText("<div id=\"body-content\">"); | |
| h_.writeText("<div id=\"doc-content\" style=\"position:relative;\">"); | |
| h_.writeText("<div id=\"mainBodyFluid\">"); | |
| h_.writeText("<h1>API Change Statistics</h1>"); | |
| DecimalFormat df2 = new DecimalFormat( "#,###,###,##0.00" ); | |
| double dd = apiDiff.pdiff; | |
| double dd2dec = new Double(df2.format(dd)).doubleValue(); | |
| h_.writeText("<p>The overall difference between API Levels " + oldAPIName + " and " + newAPIName + " is approximately <span style=\"color:222;font-weight:bold;\">" + dd2dec + "%</span>."); | |
| h_.writeText("</p>"); | |
| h_.writeText("<br>"); | |
| h_.writeText("<a name=\"numbers\"></a>"); | |
| h_.writeText("<h2>Total of Differences, by Number and Type</h2>"); | |
| h_.writeText("<p>"); | |
| h_.writeText("The table below lists the numbers of program elements (packages, classes, constructors, methods, and fields) that were added, changed, or removed. The table includes only the highest-level program elements — that is, if a class with two methods was added, the number of methods added does not include those two methods, but the number of classes added does include that class."); | |
| h_.writeText("</p>"); | |
| emitNumbersByElement(apiDiff); | |
| h_.writeText("<br>"); | |
| h_.writeText("<a name=\"packages\"></a>"); | |
| h_.writeText("<h2>Changed Packages, Sorted by Percentage Difference</h2>"); | |
| emitPackagesByDiff(apiDiff); | |
| h_.writeText("<p style=\"font-size:10px\">* See <a href=\"#calculation\">Calculation of Change Percentages</a>, below.</p>"); | |
| h_.writeText("<br>"); | |
| h_.writeText("<a name=\"classes\"></a>"); | |
| h_.writeText("<h2>Changed Classes and <i>Interfaces</i>, Sorted by Percentage Difference</h2>"); | |
| emitClassesByDiff(apiDiff); | |
| h_.writeText("<p style=\"font-size:10px\">* See <a href=\"#calculation\">Calculation of Change Percentages</a>, below.</p>"); | |
| h_.writeText("<br>"); | |
| h_.writeText("<h2 id=\"calculation\">Calculation of Change Percentages</h2>"); | |
| h_.writeText("<p>"); | |
| h_.writeText("The percent change statistic reported for all elements in the "to" API Level specification is defined recursively as follows:</p>"); | |
| h_.writeText("<pre>"); | |
| h_.writeText("Percentage difference = 100 * (added + removed + 2*changed)"); | |
| h_.writeText(" -----------------------------------"); | |
| h_.writeText(" sum of public elements in BOTH APIs"); | |
| h_.writeText("</pre>"); | |
| h_.writeText("<p>where <code>added</code> is the number of packages added, <code>removed</code> is the number of packages removed, and <code>changed</code> is the number of packages changed."); | |
| h_.writeText("This definition is applied recursively for the classes and their program elements, so the value for a changed package will be less than 1, unless every class in that package has changed."); | |
| h_.writeText("The definition ensures that if all packages are removed and all new packages are"); | |
| h_.writeText("added, the change will be 100%.</p>"); | |
| h_.writeText(" </div> "); | |
| h_.writeText(" <div id=\"footer\">"); | |
| h_.writeText(" <div id=\"copyright\">"); | |
| h_.writeText(" Except as noted, this content is licensed under "); | |
| h_.writeText(" <a href=\"https://creativecommons.org/licenses/by/2.5/\"> Creative Commons Attribution 2.5</a>."); | |
| h_.writeText(" For details and restrictions, see the <a href=\"https://developer.android.com/license.html\">Content License</a>."); | |
| h_.writeText(" </div>"); | |
| h_.writeText(" <div id=\"footerlinks\">"); | |
| h_.writeText(" <p>"); | |
| h_.writeText(" <a href=\"https://www.android.com/terms.html\">Site Terms of Service</a> -"); | |
| h_.writeText(" <a href=\"https://www.android.com/privacy.html\">Privacy Policy</a> -"); | |
| h_.writeText(" <a href=\"https://www.android.com/branding.html\">Brand Guidelines</a>"); | |
| h_.writeText(" </p>"); | |
| h_.writeText(" </div>"); | |
| h_.writeText(" </div> <!-- end footer -->"); | |
| h_.writeText(" </div><!-- end doc-content -->"); | |
| h_.writeText(" </div> <!-- end body-content --> "); | |
| h_.writeText("</BODY></HTML>"); | |
| h_.reportFile.close(); | |
| } catch(IOException e) { | |
| System.out.println("IO Error while attempting to create " + filename); | |
| System.out.println("Error: " + e.getMessage()); | |
| System.exit(1); | |
| } | |
| } | |
| /** | |
| * Emit all packages sorted by percentage difference, and a histogram | |
| * of the values. | |
| */ | |
| public void emitPackagesByDiff(APIDiff apiDiff) { | |
| Collections.sort(apiDiff.packagesChanged, new ComparePkgPdiffs()); | |
| // Write out the table start | |
| h_.writeText("<TABLE summary=\"Packages sorted by percentage difference\" WIDTH=\"100%\">"); | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <TH WIDTH=\"10%\">Percentage Difference*</TH>"); | |
| h_.writeText(" <TH>Package</TH>"); | |
| h_.writeText("</TR>"); | |
| int[] hist = new int[101]; | |
| for (int i = 0; i < 101; i++) { | |
| hist[i] = 0; | |
| } | |
| Iterator iter = apiDiff.packagesChanged.iterator(); | |
| while (iter.hasNext()) { | |
| PackageDiff pkg = (PackageDiff)(iter.next()); | |
| int bucket = (int)(pkg.pdiff); | |
| hist[bucket]++; | |
| h_.writeText("<TR>"); | |
| if (bucket != 0) | |
| h_.writeText(" <TD ALIGN=\"center\">" + bucket + "</TD>"); | |
| else | |
| h_.writeText(" <TD ALIGN=\"center\"><1</TD>"); | |
| h_.writeText(" <TD><A HREF=\"pkg_" + pkg.name_ + h_.reportFileExt + "\">" + pkg.name_ + "</A></TD>"); | |
| h_.writeText("</TR>"); | |
| } | |
| h_.writeText("</TABLE>"); | |
| /* Emit the histogram of the results | |
| h_.writeText("<hr>"); | |
| h_.writeText("<p><a name=\"packages_hist\"></a>"); | |
| h_.writeText("<TABLE summary=\"Histogram of the package percentage differences\" BORDER=\"1\" cellspacing=\"0\" cellpadding=\"0\">"); | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <TD ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Percentage<br>Difference</b></FONT></TD>"); | |
| h_.writeText(" <TD ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Frequency</b></FONT></TD>"); | |
| h_.writeText(" <TD width=\"300\" ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Percentage Frequency</b></FONT></TD>"); | |
| h_.writeText("</TR>"); | |
| double total = 0; | |
| for (int i = 0; i < 101; i++) { | |
| total += hist[i]; | |
| } | |
| for (int i = 0; i < 101; i++) { | |
| if (hist[i] != 0) { | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <TD ALIGN=\"center\">" + i + "</TD>"); | |
| h_.writeText(" <TD>" + (hist[i]/total) + "</TD>"); | |
| h_.writeText(" <TD><img alt=\"|\" src=\"../black.gif\" height=20 width=" + (hist[i]*300/total) + "></TD>"); | |
| h_.writeText("</TR>"); | |
| } | |
| } | |
| // Repeat the data in a format which is easier for spreadsheets | |
| h_.writeText("<!-- START_PACKAGE_HISTOGRAM"); | |
| for (int i = 0; i < 101; i++) { | |
| if (hist[i] != 0) { | |
| h_.writeText(i + "," + (hist[i]/total)); | |
| } | |
| } | |
| h_.writeText("END_PACKAGE_HISTOGRAM -->"); | |
| h_.writeText("</TABLE>"); | |
| */ | |
| } | |
| /** | |
| * Emit all classes sorted by percentage difference, and a histogram | |
| * of the values.. | |
| */ | |
| public void emitClassesByDiff(APIDiff apiDiff) { | |
| // Add all the changed classes to a list | |
| List allChangedClasses = new ArrayList(); | |
| Iterator iter = apiDiff.packagesChanged.iterator(); | |
| while (iter.hasNext()) { | |
| PackageDiff pkg = (PackageDiff)(iter.next()); | |
| if (pkg.classesChanged != null) { | |
| // Add the package name to the class name | |
| List cc = new ArrayList(pkg.classesChanged); | |
| Iterator iter2 = cc.iterator(); | |
| while (iter2.hasNext()) { | |
| ClassDiff classDiff = (ClassDiff)(iter2.next()); | |
| classDiff.name_ = pkg.name_ + "." + classDiff.name_; | |
| } | |
| allChangedClasses.addAll(cc); | |
| } | |
| } | |
| Collections.sort(allChangedClasses, new CompareClassPdiffs()); | |
| // Write out the table start | |
| h_.writeText("<TABLE summary=\"Classes sorted by percentage difference\" WIDTH=\"100%\">"); | |
| h_.writeText("<TR WIDTH=\"20%\">"); | |
| h_.writeText(" <TH WIDTH=\"10%\">Percentage<br>Difference*</TH>"); | |
| h_.writeText(" <TH><b>Class or <i>Interface</i></b></TH>"); | |
| h_.writeText("</TR>"); | |
| int[] hist = new int[101]; | |
| for (int i = 0; i < 101; i++) { | |
| hist[i] = 0; | |
| } | |
| iter = allChangedClasses.iterator(); | |
| while (iter.hasNext()) { | |
| ClassDiff classDiff = (ClassDiff)(iter.next()); | |
| int bucket = (int)(classDiff.pdiff); | |
| hist[bucket]++; | |
| h_.writeText("<TR>"); | |
| if (bucket != 0) | |
| h_.writeText(" <TD ALIGN=\"center\">" + bucket + "</TD>"); | |
| else | |
| h_.writeText(" <TD ALIGN=\"center\"><1</TD>"); | |
| h_.writeText(" <TD><A HREF=\"" + classDiff.name_ + h_.reportFileExt + "\">"); | |
| if (classDiff.isInterface_) | |
| h_.writeText("<i>" + classDiff.name_ + "</i></A></TD>"); | |
| else | |
| h_.writeText(classDiff.name_ + "</A></TD>"); | |
| h_.writeText("</TR>"); | |
| } | |
| h_.writeText("</TABLE>"); | |
| /* Emit the histogram of the results | |
| h_.writeText("<hr>"); | |
| h_.writeText("<p><a name=\"classes_hist\"></a>"); | |
| h_.writeText("<TABLE summary=\"Histogram of the class percentage differences\" BORDER=\"1\" cellspacing=\"0\" cellpadding=\"0\">"); | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <TD ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Percentage<br>Difference</b></FONT></TD>"); | |
| h_.writeText(" <TD ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Frequency</b></FONT></TD>"); | |
| h_.writeText(" <TD width=\"300\" ALIGN=\"center\" bgcolor=\"#EEEEFF\"><FONT size=\"+1\"><b>Percentage Frequency</b></FONT></TD>"); | |
| h_.writeText("</TR>"); | |
| double total = 0; | |
| for (int i = 0; i < 101; i++) { | |
| total += hist[i]; | |
| } | |
| for (int i = 0; i < 101; i++) { | |
| if (hist[i] != 0) { | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <TD ALIGN=\"center\">" + i + "</TD>"); | |
| h_.writeText(" <TD>" + (hist[i]/total) + "</TD>"); | |
| h_.writeText(" <TD><img alt=\"|\" src=\"../black.gif\" height=20 width=" + (hist[i]*300/total) + "></TD>"); | |
| h_.writeText("</TR>"); | |
| } | |
| } | |
| // Repeat the data in a format which is easier for spreadsheets | |
| h_.writeText("<!-- START_CLASS_HISTOGRAM"); | |
| for (int i = 0; i < 101; i++) { | |
| if (hist[i] != 0) { | |
| h_.writeText(i + "," + (hist[i]/total)); | |
| } | |
| } | |
| h_.writeText("END_CLASS_HISTOGRAM -->"); | |
| h_.writeText("</TABLE>"); | |
| */ | |
| } | |
| /** | |
| * Emit a table of numbers of removals, additions and changes by | |
| * package, class, constructor, method and field. | |
| */ | |
| public void emitNumbersByElement(APIDiff apiDiff) { | |
| // Local variables to hold the values | |
| int numPackagesRemoved = apiDiff.packagesRemoved.size(); | |
| int numPackagesAdded = apiDiff.packagesAdded.size(); | |
| int numPackagesChanged = apiDiff.packagesChanged.size(); | |
| int numClassesRemoved = 0; | |
| int numClassesAdded = 0; | |
| int numClassesChanged = 0; | |
| int numCtorsRemoved = 0; | |
| int numCtorsAdded = 0; | |
| int numCtorsChanged = 0; | |
| int numMethodsRemoved = 0; | |
| int numMethodsAdded = 0; | |
| int numMethodsChanged = 0; | |
| int numFieldsRemoved = 0; | |
| int numFieldsAdded = 0; | |
| int numFieldsChanged = 0; | |
| int numRemoved = 0; | |
| int numAdded = 0; | |
| int numChanged = 0; | |
| // Calculate the values | |
| Iterator iter = apiDiff.packagesChanged.iterator(); | |
| while (iter.hasNext()) { | |
| PackageDiff pkg = (PackageDiff)(iter.next()); | |
| numClassesRemoved += pkg.classesRemoved.size(); | |
| numClassesAdded += pkg.classesAdded.size(); | |
| numClassesChanged += pkg.classesChanged.size(); | |
| Iterator iter2 = pkg.classesChanged.iterator(); | |
| while (iter2.hasNext()) { | |
| ClassDiff classDiff = (ClassDiff)(iter2.next()); | |
| numCtorsRemoved += classDiff.ctorsRemoved.size(); | |
| numCtorsAdded += classDiff.ctorsAdded.size(); | |
| numCtorsChanged += classDiff.ctorsChanged.size(); | |
| numMethodsRemoved += classDiff.methodsRemoved.size(); | |
| numMethodsAdded += classDiff.methodsAdded.size(); | |
| numMethodsChanged += classDiff.methodsChanged.size(); | |
| numFieldsRemoved += classDiff.fieldsRemoved.size(); | |
| numFieldsAdded += classDiff.fieldsAdded.size(); | |
| numFieldsChanged += classDiff.fieldsChanged.size(); | |
| } | |
| } | |
| // Write out the table | |
| h_.writeText("<TABLE summary=\"Number of differences\" WIDTH=\"100%\">"); | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <th>Type</th>"); | |
| h_.writeText(" <TH ALIGN=\"center\"><b>Additions</b></TH>"); | |
| h_.writeText(" <TH ALIGN=\"center\"><b>Changes</b></TH>"); | |
| h_.writeText(" <TH ALIGN=\"center\">Removals</TH>"); | |
| h_.writeText(" <TH ALIGN=\"center\"><b>Total</b></TH>"); | |
| h_.writeText("</TR>"); | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <TD>Packages</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numPackagesAdded + "</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numPackagesChanged + "</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numPackagesRemoved + "</TD>"); | |
| int numPackages = numPackagesRemoved + numPackagesAdded + numPackagesChanged; | |
| h_.writeText(" <TD ALIGN=\"right\">" + numPackages + "</TD>"); | |
| h_.writeText("</TR>"); | |
| numRemoved += numPackagesRemoved; | |
| numAdded += numPackagesAdded; | |
| numChanged += numPackagesChanged; | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <TD>Classes and <i>Interfaces</i></TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numClassesAdded + "</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numClassesChanged + "</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numClassesRemoved + "</TD>"); | |
| int numClasses = numClassesRemoved + numClassesAdded + numClassesChanged; | |
| h_.writeText(" <TD ALIGN=\"right\">" + numClasses + "</TD>"); | |
| h_.writeText("</TR>"); | |
| numRemoved += numClassesRemoved; | |
| numAdded += numClassesAdded; | |
| numChanged += numClassesChanged; | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <TD>Constructors</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numCtorsAdded + "</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numCtorsChanged + "</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numCtorsRemoved + "</TD>"); | |
| int numCtors = numCtorsRemoved + numCtorsAdded + numCtorsChanged; | |
| h_.writeText(" <TD ALIGN=\"right\">" + numCtors + "</TD>"); | |
| h_.writeText("</TR>"); | |
| numRemoved += numCtorsRemoved; | |
| numAdded += numCtorsAdded; | |
| numChanged += numCtorsChanged; | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <TD>Methods</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numMethodsAdded + "</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numMethodsChanged + "</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numMethodsRemoved + "</TD>"); | |
| int numMethods = numMethodsRemoved + numMethodsAdded + numMethodsChanged; | |
| h_.writeText(" <TD ALIGN=\"right\">" + numMethods + "</TD>"); | |
| h_.writeText("</TR>"); | |
| numRemoved += numMethodsRemoved; | |
| numAdded += numMethodsAdded; | |
| numChanged += numMethodsChanged; | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <TD>Fields</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numFieldsAdded + "</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numFieldsChanged + "</TD>"); | |
| h_.writeText(" <TD ALIGN=\"right\">" + numFieldsRemoved + "</TD>"); | |
| int numFields = numFieldsRemoved + numFieldsAdded + numFieldsChanged; | |
| h_.writeText(" <TD ALIGN=\"right\">" + numFields + "</TD>"); | |
| h_.writeText("</TR>"); | |
| numRemoved += numFieldsRemoved; | |
| numAdded += numFieldsAdded; | |
| numChanged += numFieldsChanged; | |
| h_.writeText("<TR>"); | |
| h_.writeText(" <TD style=\"background-color:#FAFAFA\"><b>Total</b></TD>"); | |
| h_.writeText(" <TD style=\"background-color:#FAFAFA\" ALIGN=\"right\"><strong>" + numAdded + "</strong></TD>"); | |
| h_.writeText(" <TD style=\"background-color:#FAFAFA\" ALIGN=\"right\"><strong>" + numChanged + "</strong></TD>"); | |
| h_.writeText(" <TD style=\"background-color:#FAFAFA\" ALIGN=\"right\"><strong>" + numRemoved + "</strong></TD>"); | |
| int total = numRemoved + numAdded + numChanged; | |
| h_.writeText(" <TD style=\"background-color:#FAFAFA\" ALIGN=\"right\"><strong>" + total + "</strong></TD>"); | |
| h_.writeText("</TR>"); | |
| h_.writeText("</TABLE>"); | |
| } | |
| } | |