KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jdiff > HTMLIndexes


1 package jdiff;
2
3 import java.util.*;
4 import java.io.*;
5
6 /**
7  * Emit HTML indexes which appear in the bottom left frame in the report.
8  * All indexes are links to JDiff-generated pages.
9  *
10  * See the file LICENSE.txt for copyright details.
11  * @author Matthew Doar, doar@pobox.com
12  */

13 public class HTMLIndexes {
14
15     /** Constructor. */
16     public HTMLIndexes(HTMLReportGenerator h) {
17         h_ = h;
18     }
19
20     /** The HTMLReportGenerator instance used to write HTML. */
21     private HTMLReportGenerator h_ = null;
22     
23     /** Emit all the bottom left frame index files. */
24     public void emitAllBottomLeftFiles(String JavaDoc packagesIndexName,
25                                        String JavaDoc classesIndexName,
26                                        String JavaDoc constructorsIndexName,
27                                        String JavaDoc methodsIndexName,
28                                        String JavaDoc fieldsIndexName,
29                                        String JavaDoc allDiffsIndexName,
30                                        APIDiff apiDiff) {
31         
32         // indexType values: 0 = removals only, 1 = additions only,
33
// 2 = changes only. 3 = all differences. Run all differences
34
// first for all program element types so we know whether there
35
// are any removals etc for the allDiffs index.
36
emitBottomLeftFile(packagesIndexName, apiDiff, 3, "Package");
37         emitBottomLeftFile(classesIndexName, apiDiff, 3, "Class");
38         emitBottomLeftFile(constructorsIndexName, apiDiff, 3, "Constructor");
39         emitBottomLeftFile(methodsIndexName, apiDiff, 3, "Method");
40         emitBottomLeftFile(fieldsIndexName, apiDiff, 3, "Field");
41         // The allindex must be done last, since it uses the results from
42
// the previous ones
43
emitBottomLeftFile(allDiffsIndexName, apiDiff, 3, "All");
44         // Now generate the other indexes
45
for (int indexType = 0; indexType < 3; indexType++) {
46             emitBottomLeftFile(packagesIndexName, apiDiff, indexType, "Package");
47             emitBottomLeftFile(classesIndexName, apiDiff, indexType, "Class");
48             emitBottomLeftFile(constructorsIndexName, apiDiff, indexType, "Constructor");
49             emitBottomLeftFile(methodsIndexName, apiDiff, indexType, "Method");
50             emitBottomLeftFile(fieldsIndexName, apiDiff, indexType, "Field");
51             emitBottomLeftFile(allDiffsIndexName, apiDiff, indexType, "All");
52         }
53         if (missingSincesFile != null)
54             missingSincesFile.close();
55     }
56
57     /**
58      * Emit a single bottom left frame with the given kind of differences for
59      * the given program element type in an alphabetical index.
60      *
61      * @param indexBaseName The base name of the index file.
62      * @param apiDiff The root element containing all the API differences.
63      * @param indexType 0 = removals only, 1 = additions only,
64      * 2 = changes only, 3 = all differences,
65      * @param programElementType "Package", "Class", "Constructor",
66      * "Method", "Field" or "All".
67      */

68     public void emitBottomLeftFile(String JavaDoc indexBaseName,
69                                    APIDiff apiDiff, int indexType,
70                                    String JavaDoc programElementType) {
71         String JavaDoc filename = indexBaseName;
72         try {
73             String JavaDoc title = "JDiff";
74             if (indexType == 0) {
75                 filename += "_removals" + h_.reportFileExt;
76                 title = programElementType + " Removals Index";
77             } else if (indexType == 1) {
78                 filename += "_additions" + h_.reportFileExt;
79                 title = programElementType + " Additions Index";
80             } else if (indexType == 2) {
81                 filename += "_changes" + h_.reportFileExt;
82                 title = programElementType + " Changes Index";
83             } else if (indexType == 3) {
84                 filename += "_all" + h_.reportFileExt;
85                 title = programElementType + " Differences Index";
86             }
87                 
88             FileOutputStream fos = new FileOutputStream(filename);
89             h_.reportFile = new PrintWriter(fos);
90             h_.writeStartHTMLHeader();
91             h_.writeHTMLTitle(title);
92             h_.writeStyleSheetRef();
93             h_.writeText("</HEAD>");
94             h_.writeText("<BODY>");
95             
96             if (programElementType.compareTo("Package") == 0) {
97                 emitPackagesIndex(apiDiff, indexType);
98             } else if (programElementType.compareTo("Class") == 0) {
99                 emitClassesIndex(apiDiff, indexType);
100             } else if (programElementType.compareTo("Constructor") == 0) {
101                 emitConstructorsIndex(apiDiff, indexType);
102             } else if (programElementType.compareTo("Method") == 0) {
103                 emitMethodsIndex(apiDiff, indexType);
104             } else if (programElementType.compareTo("Field") == 0) {
105                 emitFieldsIndex(apiDiff, indexType);
106             } else if (programElementType.compareTo("All") == 0) {
107                 emitAllDiffsIndex(apiDiff, indexType);
108             } else{
109                 System.out.println("Error: unknown program element type.");
110                 System.exit(3);
111             }
112             
113             h_.writeHTMLFooter();
114             h_.reportFile.close();
115         } catch(IOException e) {
116             System.out.println("IO Error while attempting to create " + filename);
117             System.out.println("Error: " + e.getMessage());
118             System.exit(1);
119         }
120     }
121
122     /**
123      * Generate a small header of letters which link to each section, but
124      * do not emit a linked letter for the current section. Finish the list off
125      * with a link to the top of the index.
126      * Caching the results of this function would save about 10s with large APIs.
127      */

128     private void generateLetterIndex(List list, char currChar, boolean larger) {
129         if (larger)
130             return; // Currently not using the larger functionality
131
int size = -2;
132         if (larger)
133             size = -1;
134         Iterator iter = null;
135         if (isAllNames)
136             iter = allNames.iterator();
137         else
138             iter = list.iterator();
139         char oldsw = '\0';
140         while (iter.hasNext()) {
141             Index entry = (Index)(iter.next());
142             char sw = entry.name_.charAt(0);
143             char swu = Character.toUpperCase(sw);
144             if (swu != Character.toUpperCase(oldsw)) {
145                 // Don't emit a reference to the current letter
146
if (Character.toUpperCase(sw) != Character.toUpperCase(currChar)) {
147                     if (swu == '_') {
148                         h_.writeText("<a HREF=\"#" + swu + "\"><font size=\"" + size + "\">" + "underscore" + "</font></a> ");
149                     } else {
150                         h_.writeText("<a HREF=\"#" + swu + "\"><font size=\"" + size + "\">" + swu + "</font></a> ");
151                     }
152                 }
153                 oldsw = sw;
154             }
155         }
156         h_.writeText(" <a HREF=\"#topheader\"><font size=\"" + size + "\">TOP</font></a>");
157         h_.writeText("<br>");
158     }
159
160     /**
161      * Emit a header for an index, including suitable links for removed,
162      * added and changes sub-indexes.
163      */

164     private void emitIndexHeader(String JavaDoc indexName, int indexType,
165                                  boolean hasRemovals,
166                                  boolean hasAdditions, boolean hasChanges) {
167         String JavaDoc linkIndexName = indexName.toLowerCase();
168         boolean isAllDiffs = false;
169         if (indexName.compareTo("All Differences") == 0) {
170             linkIndexName = "alldiffs";
171             isAllDiffs = true;
172         }
173         h_.writeText("<a NAME=\"topheader\"></a>"); // Named anchor
174
h_.writeText("<table summary=\"Index for " + indexName + "\" width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">");
175         h_.writeText(" <tr>");
176         h_.writeText(" <td bgcolor=\"#FFFFCC\">");
177         // The index name is also a hidden link to the *index_all page
178
if (isAllDiffs)
179           h_.writeText("<font size=\"+1\"><a HREF=\"" + linkIndexName + "_index_all" + h_.reportFileExt + "\" class=\"staysblack\">" + indexName + "</a></font>");
180         else
181           h_.writeText("<font size=\"+1\"><a HREF=\"" + linkIndexName + "_index_all" + h_.reportFileExt + "\" class=\"staysblack\">All " + indexName + "</a></font>");
182         h_.writeText(" </td>");
183         h_.writeText(" </tr>");
184
185         h_.writeText(" <tr>");
186         h_.writeText(" <td bgcolor=\"#FFFFFF\">");
187         h_.writeText(" <FONT SIZE=\"-1\">");
188         if (hasRemovals) {
189           if (indexType == 0) {
190             h_.writeText("<b>Removals</b>");
191           } else {
192             h_.writeText("<A HREF=\"" + linkIndexName + "_index_removals" + h_.reportFileExt + "\" class=\"hiddenlink\">Removals</A>");
193           }
194         } else {
195             h_.writeText("<font color=\"#999999\">Removals</font>");
196         }
197         h_.writeText(" </FONT>");
198         h_.writeText(" </td>");
199         h_.writeText(" </tr>");
200
201         h_.writeText(" <tr>");
202         h_.writeText(" <td bgcolor=\"#FFFFFF\">");
203         h_.writeText(" <FONT SIZE=\"-1\">");
204         if (hasAdditions) {
205           if (indexType == 1) {
206             h_.writeText("<b>Additions</b>");
207           } else {
208             h_.writeText("<A HREF=\"" + linkIndexName + "_index_additions" + h_.reportFileExt + "\"class=\"hiddenlink\">Additions</A>");
209           }
210         } else {
211             h_.writeText("<font color=\"#999999\">Additions</font>");
212         }
213         h_.writeText(" </FONT>");
214         h_.writeText(" </td>");
215         h_.writeText(" </tr>");
216
217         h_.writeText(" <tr>");
218         h_.writeText(" <td bgcolor=\"#FFFFFF\">");
219         h_.writeText(" <FONT SIZE=\"-1\">");
220         if (hasChanges) {
221           if (indexType == 2) {
222             h_.writeText("<b>Changes</b>");
223           } else {
224             h_.writeText("<A HREF=\"" + linkIndexName + "_index_changes" + h_.reportFileExt + "\"class=\"hiddenlink\">Changes</A>");
225           }
226         } else {
227             h_.writeText("<font color=\"#999999\">Changes</font>");
228         }
229         h_.writeText(" </FONT>");
230         h_.writeText(" </td>");
231         h_.writeText(" </tr>");
232         h_.writeText(" <tr>");
233         h_.writeText(" <td>");
234         h_.writeText("<font size=\"-2\"><b>Bold</b>&nbsp;is&nbsp;New,&nbsp;<strike>strike</strike>&nbsp;is&nbsp;deleted</font>");
235         h_.writeText(" </td>");
236         h_.writeText(" </tr>");
237         h_.writeText("</table><br>");
238     }
239
240     /** Emit the index of packages, which appears in the bottom left frame. */
241     public void emitPackagesIndex(APIDiff apiDiff, int indexType) {
242         // Add all the names of packages to a new list, to be sorted later
243
packageNames = new ArrayList(); // Index[]
244
boolean hasRemovals = false;
245         if (apiDiff.packagesRemoved.size() != 0)
246             hasRemovals = true;
247         boolean hasAdditions = false;
248         if (apiDiff.packagesAdded.size() != 0)
249             hasAdditions = true;
250         boolean hasChanges = false;
251         if (apiDiff.packagesChanged.size() != 0)
252             hasChanges = true;
253         recordDiffs(hasRemovals, hasAdditions, hasChanges);
254         Iterator iter = apiDiff.packagesRemoved.iterator();
255         while ((indexType == 3 || indexType == 0) && iter.hasNext()) {
256             PackageAPI pkg = (PackageAPI)(iter.next());
257             packageNames.add(new Index(pkg.name_, 0));
258         }
259         iter = apiDiff.packagesAdded.iterator();
260         while ((indexType == 3 || indexType == 1) && iter.hasNext()) {
261             PackageAPI pkg = (PackageAPI)(iter.next());
262             packageNames.add(new Index(pkg.name_, 1));
263         }
264         iter = apiDiff.packagesChanged.iterator();
265         while ((indexType == 3 || indexType == 2) && iter.hasNext()) {
266             PackageDiff pkg = (PackageDiff)(iter.next());
267             packageNames.add(new Index(pkg.name_, 2));
268         }
269         Collections.sort(packageNames);
270
271         // No letter index needed for packages
272

273         // Now emit all the package names and links to their respective files
274
emitIndexHeader("Packages", indexType, hasRemovals, hasAdditions, hasChanges);
275
276         // Extra line because no index is emitted
277
h_.writeText("<br>");
278
279         // Package names are unique, so no need to check for duplicates.
280
iter = packageNames.iterator();
281         char oldsw = '\0';
282         while (iter.hasNext()) {
283             Index pkg = (Index)(iter.next());
284             oldsw = emitPackageIndexEntry(pkg, oldsw);
285         }
286     }
287
288     /**
289      * Emit an index entry for a package.
290      * Package names are unique, so no need to check for duplicates.
291      */

292     public char emitPackageIndexEntry(Index pkg, char oldsw) {
293         char res = oldsw;
294         // See if we are in a new section of the alphabet
295
char sw = pkg.name_.charAt(0);
296         if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
297             // No need to emit section letters for packages
298
res = sw;
299             // Add the named anchor for this new letter
300
h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
301         }
302         // Package names are unique, so no need to check for duplicates.
303
if (pkg.changeType_ == 0) {
304             h_.writeText("<A HREF=\"" + h_.reportFileName + "-summary" + h_.reportFileExt + "#" + pkg.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + pkg.name_ + "</strike></A><br>");
305         } else if (pkg.changeType_ == 1) {
306             h_.writeText("<A HREF=\"" + h_.reportFileName + "-summary" + h_.reportFileExt + "#" + pkg.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + pkg.name_ + "</b></A><br>");
307         } else if (pkg.changeType_ == 2) {
308             h_.writeText("<A HREF=\"pkg_" + pkg.name_ + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\">" + pkg.name_ + "</A><br>");
309         }
310         return res;
311     }
312
313     /**
314      * Emit all the entries and links for the given iterator
315      * to their respective files.
316      */

317     public void emitIndexEntries(Iterator iter) {
318         char oldsw = '\0';
319         int multipleMarker = 0;
320         Index currIndex = null; // The entry which is emitted
321
while (iter.hasNext()) {
322             // The next entry after the current one
323
Index nextIndex = (Index)(iter.next());
324             if (currIndex == null) {
325                 currIndex = nextIndex; // Prime the pump
326
} else {
327                 if (nextIndex.name_.compareTo(currIndex.name_) == 0) {
328                     // It's a duplicate index, so emit the name and then
329
// the indented entries
330
if (multipleMarker == 0)
331                         multipleMarker = 1; // Start of a duplicate index
332
else if (multipleMarker == 1)
333                         multipleMarker = 2; // Inside a duplicate index
334
oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker);
335                 } else {
336                     if (multipleMarker == 1)
337                         multipleMarker = 2; // Inside a duplicate index
338
oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker);
339                     multipleMarker = 0; // Not in a duplicate index any more
340
}
341                 currIndex = nextIndex;
342             }
343         }
344         // Emit the last entry left in currIndex
345
if (multipleMarker == 1)
346             multipleMarker = 2; // Inside a duplicate index
347
if (currIndex != null)
348             oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker);
349     }
350     
351     /**
352      * Whether to log all missing @since tags to a file or not.
353      * If false, just warn the user.
354      */

355     public static boolean logMissingSinces = true;
356
357     /** The file used to output details of missing @since tags. */
358     public static PrintWriter missingSincesFile = null;
359
360     /**
361      * Emit elements in the given iterator which were added and
362      * missing @since tags.
363      */

364     public void emitMissingSinces(Iterator iter) {
365 // if (!logMissingSinces)
366
// return;
367
if (missingSincesFile == null) {
368             String JavaDoc sinceFileName = h_.outputDir + JDiff.DIR_SEP + "missingSinces.txt";
369             try {
370                 FileOutputStream fos = new FileOutputStream(sinceFileName);
371                 missingSincesFile = new PrintWriter(fos);
372             } catch (IOException e) {
373                 System.out.println("IO Error while attempting to create " + sinceFileName);
374                 System.out.println("Error: " + e.getMessage());
375                 System.exit(1);
376             }
377         }
378         while (iter.hasNext()) {
379             Index currIndex = (Index)(iter.next());
380             // Only display information about added elements
381
if (currIndex.changeType_ != 1)
382                 continue;
383             String JavaDoc programElementType = currIndex.ename_;
384             String JavaDoc details = null;
385             if (programElementType.compareTo("class") == 0) {
386                 details = currIndex.pkgName_ + "." + currIndex.name_;
387                 if (currIndex.isInterface_)
388                     details = details + " Interface";
389                 else
390                     details = details + " Class";
391             } else if (programElementType.compareTo("constructor") == 0) {
392                 details = currIndex.pkgName_ + "." + currIndex.name_ + " Constructor (" + currIndex.type_ + ")";
393             } else if (programElementType.compareTo("method") == 0) {
394                 details = currIndex.pkgName_ + "." + currIndex.className_ + " " + "Method " + currIndex.name_ + "(" + currIndex.type_ + ")";
395             } else if (programElementType.compareTo("field") == 0) {
396                 details = currIndex.pkgName_ + "." + currIndex.className_ + " " + "Field " + currIndex.name_;
397             } else {
398                 System.out.println("Error: unknown program element type");
399                 System.exit(3);
400             }
401             if (currIndex.doc_ == null) {
402                 if (logMissingSinces)
403                     missingSincesFile.println("NO DOC BLOCK: " + details);
404                 else
405                     System.out.println("Warning: the doc block for the new element: " + details + " is missing, so there is no @since tag");
406             } else if (currIndex.doc_.indexOf("@since") != -1) {
407                 if (logMissingSinces)
408                     missingSincesFile.println("OK: " + details);
409             } else {
410                 if (logMissingSinces)
411                     missingSincesFile.println("MISSING @SINCE TAG: " + details);
412                 else
413                     System.out.println("Warning: the doc block for the new element: " + details + " is missing an @since tag");
414             }
415         }
416     }
417     
418     /**
419      * Emit a single entry and the link to its file.
420      *
421      * @param programElementType "Class", "Constructor",
422      * "Method", or "Field".
423      */

424     public char emitIndexEntry(Index currIndex, char oldsw, int multipleMarker) {
425         String JavaDoc programElementType = currIndex.ename_;
426         if (programElementType.compareTo("class") == 0) {
427             return emitClassIndexEntry(currIndex, oldsw, multipleMarker);
428         } else if (programElementType.compareTo("constructor") == 0) {
429             return emitCtorIndexEntry(currIndex, oldsw, multipleMarker);
430         } else if (programElementType.compareTo("method") == 0) {
431             return emitMethodIndexEntry(currIndex, oldsw, multipleMarker);
432         } else if (programElementType.compareTo("field") == 0) {
433             return emitFieldIndexEntry(currIndex, oldsw, multipleMarker);
434         } else {
435             System.out.println("Error: unknown program element type");
436             System.exit(3);
437         }
438         return '\0';
439     }
440
441     /** Emit the index of classes, which appears in the bottom left frame. */
442     public void emitClassesIndex(APIDiff apiDiff, int indexType) {
443         // Add all the names of classes to a new list, to be sorted later
444
classNames = new ArrayList(); // Index[]
445
boolean hasRemovals = false;
446         boolean hasAdditions = false;
447         boolean hasChanges = false;
448         Iterator iter = apiDiff.packagesChanged.iterator();
449         while (iter.hasNext()) {
450             PackageDiff pkgDiff = (PackageDiff)(iter.next());
451             if (pkgDiff.classesRemoved.size() != 0)
452                 hasRemovals = true;
453             if (pkgDiff.classesAdded.size() != 0)
454                 hasAdditions = true;
455             if (pkgDiff.classesChanged.size() != 0)
456                 hasChanges = true;
457             recordDiffs(hasRemovals, hasAdditions, hasChanges);
458             String JavaDoc pkgName = pkgDiff.name_;
459             Iterator iterClass = pkgDiff.classesRemoved.iterator();
460             while ((indexType == 3 || indexType == 0) && iterClass.hasNext()) {
461                 ClassAPI cls = (ClassAPI)(iterClass.next());
462                 classNames.add(new Index(cls.name_, 0, pkgName, cls.isInterface_));
463             }
464             iterClass = pkgDiff.classesAdded.iterator();
465             while ((indexType == 3 || indexType == 1) && iterClass.hasNext()) {
466                 ClassAPI cls = (ClassAPI)(iterClass.next());
467                 Index idx = new Index(cls.name_, 1, pkgName, cls.isInterface_);
468                 idx.doc_ = cls.doc_; // Used for checking @since
469
classNames.add(idx);
470             }
471             iterClass = pkgDiff.classesChanged.iterator();
472             while ((indexType == 3 || indexType == 2) && iterClass.hasNext()) {
473                 ClassDiff cls = (ClassDiff)(iterClass.next());
474                 classNames.add(new Index(cls.name_, 2, pkgName, cls.isInterface_));
475             }
476         }
477         Collections.sort(classNames);
478         emitIndexHeader("Classes", indexType, hasRemovals, hasAdditions, hasChanges);
479         emitIndexEntries(classNames.iterator());
480         if (indexType == 1)
481             emitMissingSinces(classNames.iterator());
482     }
483
484     /** Emit an index entry for a class. */
485     public char emitClassIndexEntry(Index cls, char oldsw,
486                                     int multipleMarker) {
487         char res = oldsw;
488         String JavaDoc className = cls.pkgName_ + "." + cls.name_;
489         String JavaDoc classRef = cls.pkgName_ + "." + cls.name_;
490         boolean isInterface = cls.isInterface_;
491         // See if we are in a new section of the alphabet
492
char sw = cls.name_.charAt(0);
493         if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
494             res = sw;
495             // Add the named anchor for this new letter
496
h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
497             if (sw == '_')
498                 h_.writeText("<br><b>underscore</b>&nbsp;");
499             else
500                 h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
501             generateLetterIndex(classNames, sw, false);
502         }
503         // Deal with displaying duplicate indexes
504
if (multipleMarker == 1) {
505             h_.writeText("<i>" + cls.name_ + "</i><br>");
506         }
507         if (multipleMarker != 0)
508             h_.indent(INDENT_SIZE);
509         if (cls.changeType_ == 0) {
510             // Emit a reference to the correct place for the class in the
511
// JDiff page for the package
512
h_.writeText("<A HREF=\"pkg_" + cls.pkgName_ + h_.reportFileExt +
513                          "#" + cls.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + cls.name_ + "</strike></A><br>");
514         } else if (cls.changeType_ == 1) {
515             String JavaDoc cn = cls.name_;
516             if (multipleMarker != 0)
517                 cn = cls.pkgName_;
518             if (isInterface)
519                 h_.writeText("<A HREF=\"pkg_" + cls.pkgName_ + h_.reportFileExt + "#" + cls.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><b><i>" + cn + "</i></b></A><br>");
520             else
521                 h_.writeText("<A HREF=\"pkg_" + cls.pkgName_ + h_.reportFileExt + "#" + cls.name_ + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + cn + "</b></A><br>");
522         } else if (cls.changeType_ == 2) {
523             String JavaDoc cn = cls.name_;
524             if (multipleMarker != 0)
525                 cn = cls.pkgName_;
526             if (isInterface)
527                 h_.writeText("<A HREF=\"" + classRef + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\"><i>" + cn + "</i></A><br>");
528             else
529                 h_.writeText("<A HREF=\"" + classRef + h_.reportFileExt + "\" class=\"hiddenlink\" target=\"rightframe\">" + cn + "</A><br>");
530         }
531         return res;
532     }
533     
534     /**
535      * Emit the index of all constructors, which appears in the bottom left
536      * frame.
537      */

538     public void emitConstructorsIndex(APIDiff apiDiff, int indexType) {
539         // Add all the names of constructors to a new list, to be sorted later
540
ctorNames = new ArrayList(); // Index[]
541
boolean hasRemovals = false;
542         boolean hasAdditions = false;
543         boolean hasChanges = false;
544         Iterator iter = apiDiff.packagesChanged.iterator();
545         while (iter.hasNext()) {
546             PackageDiff pkgDiff = (PackageDiff)(iter.next());
547             String JavaDoc pkgName = pkgDiff.name_;
548             Iterator iterClass = pkgDiff.classesChanged.iterator();
549             while (iterClass.hasNext()) {
550                 ClassDiff classDiff = (ClassDiff)(iterClass.next());
551                 if (classDiff.ctorsRemoved.size() != 0)
552                     hasRemovals = true;
553                 if (classDiff.ctorsAdded.size() != 0)
554                     hasAdditions = true;
555                 if (classDiff.ctorsChanged.size() != 0)
556                     hasChanges = true;
557                 recordDiffs(hasRemovals, hasAdditions, hasChanges);
558                 String JavaDoc className = classDiff.name_;
559                 Iterator iterCtor = classDiff.ctorsRemoved.iterator();
560                 while ((indexType == 3 || indexType == 0) && iterCtor.hasNext()) {
561                     ConstructorAPI ctor = (ConstructorAPI)(iterCtor.next());
562                     ctorNames.add(new Index(className, 0, pkgName, ctor.type_));
563                 }
564                 iterCtor = classDiff.ctorsAdded.iterator();
565                 while ((indexType == 3 || indexType == 1) && iterCtor.hasNext()) {
566                     ConstructorAPI ctor = (ConstructorAPI)(iterCtor.next());
567                     Index idx = new Index(className, 1, pkgName, ctor.type_);
568                     idx.doc_ = ctor.doc_; // Used for checking @since
569
ctorNames.add(idx);
570                 }
571                 iterCtor = classDiff.ctorsChanged.iterator();
572                 while ((indexType == 3 || indexType == 2) && iterCtor.hasNext()) {
573                     MemberDiff ctor = (MemberDiff)(iterCtor.next());
574                     ctorNames.add(new Index(className, 2, pkgName, ctor.newType_));
575                 }
576             }
577         }
578         Collections.sort(ctorNames);
579         emitIndexHeader("Constructors", indexType, hasRemovals, hasAdditions, hasChanges);
580         emitIndexEntries(ctorNames.iterator());
581         if (indexType == 1)
582             emitMissingSinces(ctorNames.iterator());
583     }
584
585     /** Emit an index entry for a constructor. */
586     public char emitCtorIndexEntry(Index ctor, char oldsw, int multipleMarker) {
587         char res = oldsw;
588         String JavaDoc className = ctor.pkgName_ + "." + ctor.name_;
589         String JavaDoc memberRef = ctor.pkgName_ + "." + ctor.name_;
590         String JavaDoc type = ctor.type_;
591         if (type.compareTo("void") == 0)
592             type = "";
593         String JavaDoc shownType = HTMLReportGenerator.simpleName(type);
594         // See if we are in a new section of the alphabet
595
char sw = ctor.name_.charAt(0);
596         if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
597             res = sw;
598             // Add the named anchor for this new letter
599
h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
600             if (sw == '_')
601                 h_.writeText("<br><b>underscore</b>&nbsp;");
602             else
603                 h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
604             generateLetterIndex(ctorNames, sw, false);
605         }
606         // Deal with displaying duplicate indexes
607
if (multipleMarker == 1) {
608             h_.writeText("<i>" + ctor.name_ + "</i><br>");
609         }
610         if (multipleMarker != 0)
611             h_.indent(INDENT_SIZE);
612         // Deal with each type of difference
613
// The output displayed for unique or duplicate entries is the same
614
// for constructors.
615
if (ctor.changeType_ == 0) {
616             String JavaDoc commentID = className + ".ctor_removed(" + type + ")";
617             h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + ctor.name_ + "</strike>");
618             h_.emitTypeWithParens(shownType, false);
619             h_.writeText("</A></nobr>&nbsp;constructor<br>");
620         } else if (ctor.changeType_ == 1) {
621             String JavaDoc commentID = className + ".ctor_added(" + type + ")";
622             h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + ctor.name_ + "</b>");
623             h_.emitTypeWithParens(shownType, false);
624             h_.writeText("</A></nobr>&nbsp;constructor<br>");
625         } else if (ctor.changeType_ == 2) {
626             String JavaDoc commentID = className + ".ctor_changed(" + type + ")";
627             h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + ctor.name_);
628             h_.emitTypeWithParens(shownType, false);
629             h_.writeText("</A></nobr>&nbsp;constructor<br>");
630         }
631         return res;
632     }
633
634     /**
635      * Emit the index of all methods, which appears in the bottom left frame.
636      */

637     public void emitMethodsIndex(APIDiff apiDiff, int indexType) {
638         // Add all the names of methods to a new list, to be sorted later
639
methNames = new ArrayList(); // Index[]
640
boolean hasRemovals = false;
641         boolean hasAdditions = false;
642         boolean hasChanges = false;
643         Iterator iter = apiDiff.packagesChanged.iterator();
644         while (iter.hasNext()) {
645             PackageDiff pkgDiff = (PackageDiff)(iter.next());
646             String JavaDoc pkgName = pkgDiff.name_;
647             Iterator iterClass = pkgDiff.classesChanged.iterator();
648             while (iterClass.hasNext()) {
649                 ClassDiff classDiff = (ClassDiff)(iterClass.next());
650                 if (classDiff.methodsRemoved.size() != 0)
651                     hasRemovals = true;
652                 if (classDiff.methodsAdded.size() != 0)
653                     hasAdditions = true;
654                 if (classDiff.methodsChanged.size() != 0)
655                     hasChanges = true;
656                 recordDiffs(hasRemovals, hasAdditions, hasChanges);
657                 String JavaDoc className = classDiff.name_;
658                 Iterator iterMeth = classDiff.methodsRemoved.iterator();
659                 while ((indexType == 3 || indexType == 0) && iterMeth.hasNext()) {
660                     MethodAPI meth = (MethodAPI)(iterMeth.next());
661                     methNames.add(new Index(meth.name_, 0, pkgName, className, meth.getSignature()));
662                 }
663                 iterMeth = classDiff.methodsAdded.iterator();
664                 while ((indexType == 3 || indexType == 1) && iterMeth.hasNext()) {
665                     MethodAPI meth = (MethodAPI)(iterMeth.next());
666                     Index idx = new Index(meth.name_, 1, pkgName, className, meth.getSignature());
667                     idx.doc_ = meth.doc_; // Used for checking @since
668
methNames.add(idx);
669                 }
670                 iterMeth = classDiff.methodsChanged.iterator();
671                 while ((indexType == 3 || indexType == 2) && iterMeth.hasNext()) {
672                     MemberDiff meth = (MemberDiff)(iterMeth.next());
673                     methNames.add(new Index(meth.name_, 2, pkgName, className, meth.newSignature_));
674                 }
675             }
676         }
677         Collections.sort(methNames);
678         emitIndexHeader("Methods", indexType, hasRemovals, hasAdditions, hasChanges);
679         emitIndexEntries(methNames.iterator());
680         if (indexType == 1)
681             emitMissingSinces(methNames.iterator());
682     }
683
684     /** Emit an index entry for a method. */
685     public char emitMethodIndexEntry(Index meth, char oldsw,
686                                      int multipleMarker) {
687         char res = oldsw;
688         String JavaDoc className = meth.pkgName_ + "." + meth.className_;
689         String JavaDoc memberRef = meth.pkgName_ + "." + meth.className_;
690         String JavaDoc type = meth.type_;
691         if (type.compareTo("void") == 0)
692             type = "";
693         String JavaDoc shownType = HTMLReportGenerator.simpleName(type);
694         // See if we are in a new section of the alphabet
695
char sw = meth.name_.charAt(0);
696         if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
697             res = sw;
698             // Add the named anchor for this new letter
699
h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
700             if (sw == '_')
701                 h_.writeText("<br><b>underscore</b>&nbsp;");
702             else
703                 h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
704             generateLetterIndex(methNames, sw, false);
705         }
706         // Deal with displaying duplicate indexes
707
if (multipleMarker == 1) {
708             h_.writeText("<i>" + meth.name_ + "</i><br>");
709         }
710         if (multipleMarker != 0)
711             h_.indent(INDENT_SIZE);
712         // Deal with each type of difference
713
if (meth.changeType_ == 0) {
714             String JavaDoc commentID = className + "." + meth.name_ + "_removed(" + type + ")";
715             if (multipleMarker == 0) {
716                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + meth.name_ + "</strike>");
717                 h_.emitTypeWithParens(shownType, false);
718             } else {
719                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;<strike>");
720                 h_.emitTypeWithParens(shownType, false);
721                 h_.writeText("</strike>&nbsp;in&nbsp;" + className);
722             }
723             h_.writeText("</A></nobr><br>");
724         } else if (meth.changeType_ == 1) {
725             String JavaDoc commentID = className + "." + meth.name_ + "_added(" + type + ")";
726             if (multipleMarker == 0) {
727                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><b>" + meth.name_ + "</b>");
728                 h_.emitTypeWithParens(shownType, false);
729             } else {
730                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;<b>");
731                 h_.emitTypeWithParens(shownType, false);
732                 h_.writeText("</b>&nbsp;in&nbsp;" + className);
733             }
734             h_.writeText("</A></nobr><br>");
735         } else if (meth.changeType_ == 2) {
736             String JavaDoc commentID = className + "." + meth.name_ + "_changed(" + type + ")";
737             if (multipleMarker == 0) {
738                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + meth.name_);
739                 h_.emitTypeWithParens(shownType, false);
740             } else {
741                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">type&nbsp;");
742                 h_.emitTypeWithParens(shownType, false);
743                 h_.writeText("&nbsp;in&nbsp;" + className);
744             }
745             h_.writeText("</A></nobr><br>");
746         }
747         return res;
748     }
749
750     /**
751      * Emit the index of all fields, which appears in the bottom left frame.
752      */

753     public void emitFieldsIndex(APIDiff apiDiff, int indexType) {
754         // Add all the names of fields to a new list, to be sorted later
755
fieldNames = new ArrayList(); // Index[]
756
boolean hasRemovals = false;
757         boolean hasAdditions = false;
758         boolean hasChanges = false;
759         Iterator iter = apiDiff.packagesChanged.iterator();
760         while (iter.hasNext()) {
761             PackageDiff pkgDiff = (PackageDiff)(iter.next());
762             String JavaDoc pkgName = pkgDiff.name_;
763             Iterator iterClass = pkgDiff.classesChanged.iterator();
764             while (iterClass.hasNext()) {
765                 ClassDiff classDiff = (ClassDiff)(iterClass.next());
766                 if (classDiff.fieldsRemoved.size() != 0)
767                     hasRemovals = true;
768                 if (classDiff.fieldsAdded.size() != 0)
769                     hasAdditions = true;
770                 if (classDiff.fieldsChanged.size() != 0)
771                     hasChanges = true;
772                 recordDiffs(hasRemovals, hasAdditions, hasChanges);
773                 String JavaDoc className = classDiff.name_;
774                 Iterator iterField = classDiff.fieldsRemoved.iterator();
775                 while ((indexType == 3 || indexType == 0) && iterField.hasNext()) {
776                     FieldAPI fld = (FieldAPI)(iterField.next());
777                     fieldNames.add(new Index(fld.name_, 0, pkgName, className, fld.type_, true));
778                 }
779                 iterField = classDiff.fieldsAdded.iterator();
780                 while ((indexType == 3 || indexType == 1) && iterField.hasNext()) {
781                     FieldAPI fld = (FieldAPI)(iterField.next());
782                     Index idx = new Index(fld.name_, 1, pkgName, className, fld.type_, true);
783                     idx.doc_ = fld.doc_; // Used for checking @since
784
fieldNames.add(idx);
785                 }
786                 iterField = classDiff.fieldsChanged.iterator();
787                 while ((indexType == 3 || indexType == 2) && iterField.hasNext()) {
788                     MemberDiff fld = (MemberDiff)(iterField.next());
789                     fieldNames.add(new Index(fld.name_, 2, pkgName, className, fld.newType_, true));
790                 }
791             }
792         }
793         Collections.sort(fieldNames);
794         emitIndexHeader("Fields", indexType, hasRemovals, hasAdditions, hasChanges);
795         emitIndexEntries(fieldNames.iterator());
796         if (indexType == 1)
797             emitMissingSinces(fieldNames.iterator());
798     }
799
800     /** Emit an index entry for a field. */
801     public char emitFieldIndexEntry(Index fld, char oldsw,
802                                     int multipleMarker) {
803         char res = oldsw;
804         String JavaDoc className = fld.pkgName_ + "." + fld.className_;
805         String JavaDoc memberRef = fld.pkgName_ + "." + fld.className_;
806         String JavaDoc type = fld.type_;
807         if (type.compareTo("void") == 0)
808             type = "";
809         String JavaDoc shownType = HTMLReportGenerator.simpleName(type);
810         // See if we are in a new section of the alphabet
811
char sw = fld.name_.charAt(0);
812         if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) {
813             res = sw;
814             // Add the named anchor for this new letter
815
h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>");
816             if (sw == '_')
817                 h_.writeText("<br><b>underscore</b>&nbsp;");
818             else
819                 h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font>&nbsp;");
820             generateLetterIndex(fieldNames, sw, false);
821         }
822         // Deal with displaying duplicate indexes
823
if (multipleMarker == 1) {
824             h_.writeText("<i>" + fld.name_ + "</i><br>");
825         }
826         if (multipleMarker != 0) {
827 // More context than this is helpful here: h_.indent(INDENT_SIZE);
828
h_.writeText("&nbsp;in&nbsp;");
829         }
830         // Deal with each type of difference
831
if (fld.changeType_ == 0) {
832             String JavaDoc commentID = className + "." + fld.name_;
833             if (multipleMarker == 0) {
834                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + fld.name_ + "</strike></A>");
835                 h_.writeText("</nobr><br>");
836             } else {
837                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\"><strike>" + className + "</strike></A>");
838                 h_.writeText("</nobr><br>");
839             }
840         } else if (fld.changeType_ == 1) {
841             String JavaDoc commentID = className + "." + fld.name_;
842             if (multipleMarker == 0) {
843                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + fld.name_ + "</A>");
844                 h_.writeText("</nobr><br>");
845             } else {
846                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + className + "</A>");
847                 h_.writeText("</nobr><br>");
848             }
849         } else if (fld.changeType_ == 2) {
850             String JavaDoc commentID = className + "." + fld.name_;
851             if (multipleMarker == 0) {
852                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + fld.name_ + "</A>");
853                 h_.writeText("</nobr><br>");
854             } else {
855                 h_.writeText("<nobr><A HREF=\"" + memberRef + h_.reportFileExt + "#" + commentID + "\" class=\"hiddenlink\" target=\"rightframe\">" + className + "</A>");
856                 h_.writeText("</nobr><br>");
857             }
858         }
859         return res;
860     }
861
862     /**
863      * Emit the index of all changes, which appears in the bottom left frame.
864      * Has to be run after all the other indexes have been written, since it
865      * uses data from when they are generated.
866      */

867     public void emitAllDiffsIndex(APIDiff apiDiff, int indexType) {
868         allNames = new ArrayList(); // Index[]
869
// Add all the changes into one big list, and sort it by name,
870
// ignoring case
871
allNames.addAll(packageNames);
872         allNames.addAll(classNames);
873         allNames.addAll(ctorNames);
874         allNames.addAll(methNames);
875         allNames.addAll(fieldNames);
876         // Compares two Index objects' names, ignoring case differences.
877
Collections.sort(allNames);
878
879         emitIndexHeader("All Differences", indexType, atLeastOneRemoval,
880                         atLeastOneAddition, atLeastOneChange);
881
882         // Tell generateLetterIndex to use allNames as the list when
883
// using the other methods to generate the indexes.
884
isAllNames = true;
885         
886         // Now emit a line for each entry in the list in the appropriate
887
// format for each program element
888
Iterator iter = allNames.iterator();
889         char oldsw = '\0';
890         int multipleMarker = 0;
891         Index currIndex = null; // The entry which is emitted
892
while (iter.hasNext()) {
893             // The next entry after the current one
894
Index nextIndex = (Index)(iter.next());
895             if (currIndex == null) {
896                 currIndex = nextIndex; // Prime the pump
897
} else {
898                 if (nextIndex.name_.compareTo(currIndex.name_) == 0) {
899                     // It's a duplicate index, so emit the name and then
900
// the indented entries
901
if (multipleMarker == 0)
902                         multipleMarker = 1; // Start of a duplicate index
903
else if (multipleMarker == 1)
904                         multipleMarker = 2; // Inside a duplicate index
905
oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
906                 } else {
907                     if (multipleMarker == 1)
908                         multipleMarker = 2; // Inside a duplicate index
909
oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
910                     multipleMarker = 0; // Not in a duplicate index any more
911
}
912                 currIndex = nextIndex;
913             }
914         }
915         // Emit the last entry left in currIndex
916
if (multipleMarker == 1)
917             multipleMarker = 2; // Inside a duplicate index
918
if (currIndex != null)
919             oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker);
920
921         // Tell generateLetterIndex to stop using allNames as the list when
922
// using the other methods to generate the indexes.
923
isAllNames = false;
924     }
925
926     /** Call the appropriate *IndexEntry method for each entry. */
927     public char emitIndexEntryForAny(Index currIndex, char oldsw,
928                                      int multipleMarker) {
929         if (currIndex.ename_.compareTo("package") == 0) {
930             h_.writeText("<!-- Package " + currIndex.name_ + " -->");
931             return emitPackageIndexEntry(currIndex, oldsw);
932         } else if (currIndex.ename_.compareTo("class") == 0) {
933             h_.writeText("<!-- Class " + currIndex.name_ + " -->");
934             return emitClassIndexEntry(currIndex, oldsw, multipleMarker);
935         } else if (currIndex.ename_.compareTo("constructor") == 0) {
936             h_.writeText("<!-- Constructor " + currIndex.name_ + " -->");
937             return emitCtorIndexEntry(currIndex, oldsw, multipleMarker);
938         } else if (currIndex.ename_.compareTo("method") == 0) {
939             h_.writeText("<!-- Method " + currIndex.name_ + " -->");
940             return emitMethodIndexEntry(currIndex, oldsw, multipleMarker);
941         } else if (currIndex.ename_.compareTo("field") == 0) {
942             h_.writeText("<!-- Field " + currIndex.name_ + " -->");
943             return emitFieldIndexEntry(currIndex, oldsw, multipleMarker);
944         }
945         return '\0';
946     }
947
948     /** The list of all changes for all program elements. */
949     private List allNames = null; // Index[]
950

951     /** The list of all package changes. */
952     private List packageNames = null; // Index[]
953

954     /** The list of all class changes. */
955     private List classNames = null; // Index[]
956

957     /** The list of all constructor changes. */
958     private List ctorNames = null; // Index[]
959

960     /** The list of all method changes. */
961     private List methNames = null; // Index[]
962

963     /** The list of all field changes. */
964     private List fieldNames = null; // Index[]
965

966     /** If set, then use allNames to generate the letter indexes. */
967     private boolean isAllNames = false;
968
969     /**
970      * If any of the parameters are set, then set the respective atLeastOne
971      * variable, used to generate the links at the top of the allDiffs index.
972      * Never unset an atLeastOne variable.
973      */

974     private void recordDiffs(boolean hasRemovals, boolean hasAdditions,
975                         boolean hasChanges) {
976         if (hasRemovals)
977             atLeastOneRemoval = true;
978         if (hasAdditions)
979             atLeastOneAddition = true;
980         if (hasChanges)
981             atLeastOneChange = true;
982     }
983
984     /** Set if there was at least one removal in the entire API. */
985     private boolean atLeastOneRemoval = false;
986
987     /** Set if there was at least one addition in the entire API. */
988     private boolean atLeastOneAddition = false;
989
990     /** Set if there was at least one change in the entire API. */
991     private boolean atLeastOneChange = false;
992
993     /**
994      * The number of non-breaking spaces to indent a duplicate indexes'
995      * entries by.
996      */

997     private final int INDENT_SIZE = 2;
998 }
999
1000/**
1001 * Class used to produce indexes of packages and classes.
1002 *
1003 * See the file LICENSE.txt for copyright details.
1004 * @author Matthew Doar, doar@pobox.com
1005 */

1006class Index implements Comparable JavaDoc {
1007
1008    /** The name of the program element this Index object represents. */
1009    public String JavaDoc ename_ = null;
1010
1011    /** Name of the changed package, class or member. */
1012    public String JavaDoc name_ = null;
1013    
1014    /** Type of change. 0 = remove, 1 = add, 2 = change. */
1015    public int changeType_;
1016    
1017    /** Name of the changed package if name_ is a class name. */
1018    public String JavaDoc pkgName_ = null;
1019    
1020    /** Set if this class is an interface. */
1021    public boolean isInterface_= false;
1022    
1023    /** The doc block of added elements, default is null. */
1024    public String JavaDoc doc_ = null;
1025    
1026    /**
1027     * The new member type. For methods, this is the signature.
1028     */

1029    public String JavaDoc type_ = null;
1030
1031    /**
1032     * The class name. Only used by methods.
1033     */

1034    public String JavaDoc className_ = null;
1035
1036    /** Constructor for packages. */
1037    public Index(String JavaDoc name, int changeType) {
1038        ename_ = "package";
1039        name_ = name;
1040        changeType_ = changeType;
1041    }
1042    
1043    /** Constructor for classes. */
1044    public Index(String JavaDoc name, int changeType, String JavaDoc pkgName, boolean isInterface) {
1045        ename_ = "class";
1046        name_ = name;
1047        changeType_ = changeType;
1048        pkgName_ = pkgName;
1049        isInterface_ = isInterface;
1050    }
1051        
1052    /** Constructor for constructors. */
1053    public Index(String JavaDoc name, int changeType, String JavaDoc pkgName, String JavaDoc type) {
1054        ename_ = "constructor";
1055        name_ = name;
1056        changeType_ = changeType;
1057        pkgName_ = pkgName;
1058        type_ = type;
1059    }
1060        
1061    /** Constructor for methods. */
1062    public Index(String JavaDoc name, int changeType, String JavaDoc pkgName,
1063                 String JavaDoc className, String JavaDoc type) {
1064        ename_ = "method";
1065        name_ = name;
1066        changeType_ = changeType;
1067        pkgName_ = pkgName;
1068        className_ = className;
1069        type_ = type;
1070    }
1071        
1072    /**
1073     * Constructor for fields.
1074     *
1075     * The boolean <code>fld</code> is simply there to differentiate this
1076     * constructor from the one for methods.
1077     */

1078    public Index(String JavaDoc name, int changeType, String JavaDoc pkgName,
1079                 String JavaDoc className, String JavaDoc type, boolean fld) {
1080        ename_ = "field";
1081        name_ = name;
1082        changeType_ = changeType;
1083        pkgName_ = pkgName;
1084        className_ = className;
1085        type_ = type;
1086    }
1087        
1088        
1089    /** Compare two Index objects by their simple names, ignoring case. */
1090    public int compareTo(Object JavaDoc o) {
1091        return name_.compareToIgnoreCase(((Index)o).name_);
1092    }
1093    
1094}
1095
1096
Popular Tags