KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jdiff > Diff


1 package jdiff;
2
3 import java.io.*;
4 import java.util.*;
5
6 /**
7  * Class to generate colored differences between two sections of HTML text.
8  *
9  * See the file LICENSE.txt for copyright details.
10  * @author Matthew Doar, doar@pobox.com
11  */

12 class Diff {
13
14     /**
15      * Save the differences between the two strings in a DiffOutput object
16      * for later use.
17      *
18      * @param id A per-package unique identifier for each documentation
19      * change.
20      */

21     static String JavaDoc saveDocDiffs(String JavaDoc pkgName, String JavaDoc className,
22                                String JavaDoc oldDoc, String JavaDoc newDoc,
23                                String JavaDoc id, String JavaDoc title) {
24         // Generate the string which will link to this set of diffs
25
if (noDocDiffs)
26             return "Documentation changed from ";
27         if (oldDoc == null || newDoc == null) {
28             return "Documentation changed from ";
29         }
30
31         // Generate the differences.
32
generateDiffs(pkgName, className, oldDoc, newDoc, id, title);
33
34         return "Documentation <a HREF=\"" + diffFileName + pkgName +
35             HTMLReportGenerator.reportFileExt + "#" + id +
36             "\">changed</a> from ";
37     }
38     
39     /**
40      * Generate the differences.
41      */

42     static void generateDiffs(String JavaDoc pkgName, String JavaDoc className,
43                               String JavaDoc oldDoc, String JavaDoc newDoc,
44                               String JavaDoc id, String JavaDoc title) {
45         String JavaDoc[] oldDocWords = parseDoc(oldDoc);
46         String JavaDoc[] newDocWords = parseDoc(newDoc);
47
48         DiffMyers diff = new DiffMyers(oldDocWords, newDocWords);
49         DiffMyers.change script = diff.diff_2(false);
50         script = mergeDiffs(oldDocWords, newDocWords, script);
51         String JavaDoc text = "<A NAME=\"" + id + "\"></A>" + title + "<br><br>";
52         // Generate the differences in blockquotes to cope with unterminated
53
// HTML tags
54
text += "<blockquote>";
55         text = addDiffs(oldDocWords, newDocWords, script, text);
56         text += "</blockquote>";
57         docDiffs.add(new DiffOutput(pkgName, className, id, title, text));
58     }
59
60     /**
61      * Convert the string to an array of strings, but don't break HTML tags up.
62      */

63     static String JavaDoc[] parseDoc(String JavaDoc doc) {
64         String JavaDoc delimiters = " .,;:?!(){}[]\"'~@#$%^&*+=_-|\\<>/";
65         StringTokenizer st = new StringTokenizer(doc, delimiters, true);
66         List docList = new ArrayList();
67         boolean inTag = false;
68         String JavaDoc tag = null;
69         while (st.hasMoreTokens()) {
70             String JavaDoc tok = st.nextToken();
71             if (!inTag) {
72                 if (tok.compareTo("<") == 0) {
73                     tag = tok;
74                     if (st.hasMoreTokens()) {
75                         // See if this really is a tag
76
tok = st.nextToken();
77                         char ch = tok.charAt(0);
78                         if (Character.isLetter(ch) || ch == '/') {
79                             inTag = true;
80                             tag += tok;
81                         }
82                     }
83                     if (!inTag)
84                       docList.add(tag);
85                 } else {
86                     docList.add(tok);
87                 }
88             } else {
89                 // Add all tokens to the tag until the closing > is seen
90
if (tok.compareTo(">") == 0) {
91                     inTag = false;
92                     tag += tok;
93                     docList.add(tag);
94                 } else {
95                     tag += tok;
96                 }
97             }
98         }
99         if (inTag) {
100             // An unterminated tag, or more likely, < used instead of &lt;
101
// There are no nested tags such as <a <b>> in HTML
102
docList.add(tag);
103         }
104         String JavaDoc[] docWords = new String JavaDoc[docList.size()];
105         docWords = (String JavaDoc[])docList.toArray(docWords);
106         return docWords;
107     }
108
109     /**
110      * For improved readability, merge changes of the form
111      * "delete 1, insert 1, space, delete 1, insert 1"
112      * to
113      * "delete 3, insert 3" (including the space).
114      *
115      * @param oldDocWords The original documentation as a String array
116      * @param newDocWords The new documentation as a String array
117      */

118     static DiffMyers.change mergeDiffs(String JavaDoc[] oldDocWords, String JavaDoc[] newDocWords,
119                                        DiffMyers.change script) {
120         if (script.link == null)
121             return script; // Only one change
122
DiffMyers.change hunk = script;
123         DiffMyers.change lasthunk = null; // Set to the last potential hunk
124
int startOld = 0;
125         for (; hunk != null; hunk = hunk.link) {
126             int deletes = hunk.deleted;
127             int inserts = hunk.inserted;
128             if (lasthunk == null) {
129                 if (deletes == 1 && inserts == 1) {
130                     // This is the start of a potential merge
131
lasthunk = hunk;
132                 }
133                 continue;
134             } else {
135                 int first0 = hunk.line0; // Index of first deleted word
136
int first1 = hunk.line1; // Index of first inserted word
137
if (deletes == 1 && inserts == 1 &&
138                     oldDocWords[first0 - 1].compareTo(" ") == 0 &&
139                     newDocWords[first1 - 1].compareTo(" ") == 0 &&
140                     first0 == lasthunk.line0 + lasthunk.deleted + 1 &&
141                     first1 == lasthunk.line1 + lasthunk.inserted + 1) {
142                     // Merge this change into the last change
143
lasthunk.deleted += 2;
144                     lasthunk.inserted += 2;
145                     lasthunk.link = hunk.link;
146                 } else {
147                     lasthunk = null;
148                 }
149             }
150         }
151         return script;
152     }
153
154     /**
155      * Add the differences to the text passed in. The old documentation is
156      * edited using the edit script provided by the DiffMyers object.
157      * Do not display diffs in HTML tags.
158      *
159      * @param oldDocWords The original documentation as a String array
160      * @param newDocWords The new documentation as a String array
161      * @return The text for this documentation difference
162      */

163     static String JavaDoc addDiffs(String JavaDoc[] oldDocWords, String JavaDoc[] newDocWords,
164                            DiffMyers.change script, String JavaDoc text) {
165         String JavaDoc res = text;
166         DiffMyers.change hunk = script;
167         int startOld = 0;
168         if (trace) {
169             System.out.println("Old Text:");
170             for (int i = 0; i < oldDocWords.length; i++) {
171                 System.out.print(oldDocWords[i]);
172             }
173             System.out.println(":END");
174             System.out.println("New Text:");
175             for (int i = 0; i < newDocWords.length; i++) {
176                 System.out.print(newDocWords[i]);
177             }
178             System.out.println(":END");
179         }
180
181         for (; hunk != null; hunk = hunk.link) {
182             int deletes = hunk.deleted;
183             int inserts = hunk.inserted;
184             if (deletes == 0 && inserts == 0) {
185                 continue; // Not clear how this would occur, but handle it
186
}
187
188             // Determine the range of word and delimiter numbers involved
189
// in each file.
190
int first0 = hunk.line0; // Index of first deleted word
191
// Index of last deleted word, invalid if deletes == 0
192
int last0 = hunk.line0 + hunk.deleted - 1;
193             int first1 = hunk.line1; // Index of first inserted word
194
// Index of last inserted word, invalid if inserts == 0
195
int last1 = hunk.line1 + hunk.inserted - 1;
196             
197             if (trace) {
198                 System.out.println("HUNK: ");
199                 System.out.println("inserts: " + inserts);
200                 System.out.println("deletes: " + deletes);
201                 System.out.println("first0: " + first0);
202                 System.out.println("last0: " + last0);
203                 System.out.println("first1: " + first1);
204                 System.out.println("last1: " + last1);
205             }
206
207             // Emit the original document up to this change
208
for (int i = startOld; i < first0; i++) {
209                 res += oldDocWords[i];
210             }
211             // Record where to start the next hunk from
212
startOld = last0 + 1;
213             // Emit the deleted words, but struck through
214
// but do not emit deleted HTML tags
215
if (deletes != 0) {
216                 boolean inStrike = false;
217                 for (int i = first0; i <= last0; i++) {
218                     if (!oldDocWords[i].startsWith("<") &&
219                         !oldDocWords[i].endsWith(">")) {
220                         if (!inStrike) {
221                             if (deleteEffect == 0)
222                                 res += "<strike>";
223                             else if (deleteEffect == 1)
224                                 res += "<span style=\"background: #FFCCCC\">";
225                             inStrike = true;
226                         }
227                         res += oldDocWords[i];
228                     }
229                 }
230                 if (inStrike) {
231                     if (deleteEffect == 0)
232                         res += "</strike>";
233                     else if (deleteEffect == 1)
234                         res += "</span>";
235                 }
236             }
237             // Emit the inserted words, but do not emphasise new HTML tags
238
if (inserts != 0) {
239                 boolean inEmph = false;
240                 for (int i = first1; i <= last1; i++) {
241                     if (!newDocWords[i].startsWith("<") &&
242                         !newDocWords[i].endsWith(">")) {
243                         if (!inEmph) {
244                             if (insertEffect == 0)
245                                 res += "<font color=\"red\">";
246                             else if (insertEffect == 1)
247                                 res += "<span style=\"background: #FFFF00\">";
248                             inEmph = true;
249                         }
250                     }
251                     res += newDocWords[i];
252                 }
253                 if (inEmph) {
254                     if (insertEffect == 0)
255                         res += "</font>";
256                     else if (insertEffect == 1)
257                         res += "</span>";
258                 }
259             }
260         } //for (; hunk != null; hunk = hunk.link)
261
// Print out the remaining part of the old text
262
for (int i = startOld; i < oldDocWords.length; i++) {
263             res += oldDocWords[i];
264         }
265         return res;
266     }
267
268     /**
269      * Emit all the documentation differences into one file per package.
270      */

271     static void emitDocDiffs(String JavaDoc fullReportFileName) {
272         Collections.sort(docDiffs);
273
274         DiffOutput[] docDiffsArr = new DiffOutput[docDiffs.size()];
275         docDiffsArr = (DiffOutput[])docDiffs.toArray(docDiffsArr);
276
277         for (int i = 0; i < docDiffsArr.length; i++) {
278             DiffOutput diffOutput = docDiffsArr[i];
279             if (currPkgName == null ||
280                 currPkgName.compareTo(diffOutput.pkgName_) != 0) {
281                 // Open a different file for each package, add the HTML header,
282
// the navigation bar and some preamble.
283
if (currPkgName != null)
284                     closeDiffFile(); // Close the existing file
285
// Create the HTML link to the previous package
286
String JavaDoc prevPkgName = currPkgName;
287                 if (currPkgName != null) {
288                     prevPkgName = diffFileName + docDiffsArr[i-1].pkgName_ +
289                     HTMLReportGenerator.reportFileExt;
290                 }
291                 // Set the current package name
292
currPkgName = diffOutput.pkgName_;
293                 // Create the HTML link to the next package
294
String JavaDoc nextPkgName = null;
295                 for (int j = i; j < docDiffsArr.length; j++) {
296                     if (currPkgName.compareTo(docDiffsArr[j].pkgName_) != 0) {
297                         nextPkgName = diffFileName + docDiffsArr[j].pkgName_ +
298                             HTMLReportGenerator.reportFileExt;
299                         break;
300                     }
301                 }
302
303                 String JavaDoc fullDiffFileName = fullReportFileName +
304                     JDiff.DIR_SEP + diffFileName + currPkgName +
305                     HTMLReportGenerator.reportFileExt;
306                 // Create the output file
307
try {
308                     FileOutputStream fos = new FileOutputStream(fullDiffFileName);
309                     diffFile = new PrintWriter(fos);
310                     
311                     // Write the HTML header
312
diffFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\"\"" + RootDocToXML.baseURI + "/TR/REC-html40/frameset.dtd\">");
313                     diffFile.println("<HTML>");
314                     diffFile.println("<HEAD>");
315                     diffFile.println("<meta name=\"generator\" content=\"JDiff v" + JDiff.version + "\">");
316                     diffFile.println("<!-- Generated by the JDiff Javadoc doclet -->");
317                     diffFile.println("<!-- (" + JDiff.jDiffLocation + ") -->");
318 // diffFile.println("<!-- on " + new Date() + " -->");
319
diffFile.println("<meta name=\"description\" content=\"" + JDiff.jDiffDescription + "\">");
320                     diffFile.println("<meta name=\"keywords\" content=\"" + JDiff.jDiffKeywords + "\">");
321                     diffFile.println("<LINK REL=\"stylesheet\" TYPE=\"text/css\" HREF=\"" + "../" + "stylesheet-jdiff.css\" TITLE=\"Style\">");
322                     diffFile.println("<TITLE>");
323                     diffFile.println(currPkgName + " Documentation Differences");
324                     diffFile.println("</TITLE>");
325                     diffFile.println("</HEAD>");
326                     diffFile.println("<BODY>");
327                                         
328                     // Write the navigation bar
329
diffFile.println("<!-- Start of nav bar -->");
330                     diffFile.println("<TABLE summary=\"Navigation bar\" BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">");
331                     diffFile.println("<TR>");
332                     diffFile.println("<TD COLSPAN=2 BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\">");
333                     diffFile.println(" <TABLE summary=\"Navigation bar\" BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"3\">");
334                     diffFile.println(" <TR ALIGN=\"center\" VALIGN=\"top\">");
335                     // Always have a link to the Javadoc files
336
String JavaDoc pkgRef = currPkgName;
337                     pkgRef = pkgRef.replace('.', '/');
338                     pkgRef = HTMLReportGenerator.newDocPrefix + pkgRef + "/package-summary";
339                     diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + pkgRef + ".html\" target=\"_top\"><FONT CLASS=\"NavBarFont1\"><B><tt>" + APIDiff.newAPIName_ + "</tt></B></FONT></A>&nbsp;</TD>");
340                     diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + HTMLReportGenerator.reportFileName + "-summary" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Overview</B></FONT></A>&nbsp;</TD>");
341                     diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Package</FONT>&nbsp;</TD>");
342                     diffFile.println(" <TD BGCOLOR=\"#FFFFFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Class</FONT>&nbsp;</TD>");
343                     if (!Diff.noDocDiffs) {
344                         diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + Diff.diffFileName + "index" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Text Changes</B></FONT></A>&nbsp;</TD>");
345                     }
346                     if (HTMLReportGenerator.doStats) {
347                         diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_statistics" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Statistics</B></FONT></A>&nbsp;</TD>");
348                     }
349                     diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_help" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Help</B></FONT></A>&nbsp;</TD>");
350                     diffFile.println(" </TR>");
351                     diffFile.println(" </TABLE>");
352                     diffFile.println("</TD>");
353                     
354                     // The right hand side title
355
diffFile.println("<TD ALIGN=\"right\" VALIGN=\"top\" ROWSPAN=3><EM><b>Generated by<br><a HREF=\"" + JDiff.jDiffLocation + "\" class=\"staysblack\" target=\"_top\">JDiff</a></b></EM></TD>");
356                     diffFile.println("</TR>");
357                     
358                     // Links for previous and next, and frames and no frames
359
diffFile.println("<TR>");
360                     diffFile.println(" <TD BGCOLOR=\"" + HTMLReportGenerator.bgcolor + "\" CLASS=\"NavBarCell2\"><FONT SIZE=\"-2\">");
361                     if (prevPkgName != null)
362                         diffFile.println(" <A HREF=\"" + prevPkgName + "\"><B>PREV PACKAGE</B></A> &nbsp;");
363                     else
364                         diffFile.println(" <B>PREV PACKAGE</B> &nbsp;");
365                     if (nextPkgName != null)
366                         diffFile.println(" &nbsp;<A HREF=\"" + nextPkgName + "\"><B>NEXT PACKAGE</B></A>");
367                     else
368                         diffFile.println(" &nbsp;<B>NEXT PACKAGE</B>");
369                     diffFile.println("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
370                     diffFile.println(" <A HREF=\"" + "../" + HTMLReportGenerator.reportFileName + HTMLReportGenerator.reportFileExt + "\" TARGET=\"_top\"><B>FRAMES</B></A> &nbsp;");
371                     diffFile.println(" &nbsp;<A HREF=\"" + diffFileName + currPkgName + HTMLReportGenerator.reportFileExt + "\" TARGET=\"_top\"><B>NO FRAMES</B></A></FONT></TD>");
372                     diffFile.println(" <TD BGCOLOR=\"" + HTMLReportGenerator.bgcolor + "\" CLASS=\"NavBarCell2\">&nbsp;</TD>");
373                     diffFile.println("</TR>");
374                     
375                     diffFile.println("</TABLE>");
376                     diffFile.println("<HR>");
377                     diffFile.println("<!-- End of nav bar -->");
378                     
379                     diffFile.println("<h2>");
380                     diffFile.println(currPkgName + " Documentation Differences");
381                     diffFile.println("</h2>");
382                     diffFile.println();
383                     diffFile.println("<blockquote>");
384                     diffFile.println("This file contains all the changes in documentation in the package <code>" + currPkgName + "</code> as colored differences.");
385                     if (deleteEffect == 0)
386                         diffFile.println("Deletions are shown <strike>like this</strike>, and");
387                     else if (deleteEffect == 1)
388                         diffFile.println("Deletions are shown <span style=\"background: #FFCCCC\">like this</span>, and");
389                     if (insertEffect == 0)
390                         diffFile.println("additions are shown in red <font color=\"red\">like this</font>.");
391                     else if (insertEffect == 1)
392                         diffFile.println("additions are shown <span style=\"background: #FFFF00\">like this</span>.");
393                     diffFile.println("</blockquote>");
394                     
395                     diffFile.println("<blockquote>");
396                     diffFile.println("If no deletions or additions are shown in an entry, the HTML tags will be what has changed. The <i>new</i> HTML tags are shown in the differences. ");
397                     diffFile.println("If no documentation existed, and then some was added in a later version, this change is noted in the appropriate class pages of differences, but the change is not shown on this page. Only changes in existing text are shown here. ");
398                     diffFile.println("Similarly, documentation which was inherited from another class or interface is not shown here.");
399                     diffFile.println("</blockquote>");
400                     
401                     diffFile.println("<blockquote>");
402                     diffFile.println(" Note that an HTML error in the new documentation may cause the display of other documentation changes to be presented incorrectly. For instance, failure to close a &lt;code&gt; tag will cause all subsequent paragraphs to be displayed differently.");
403                     diffFile.println("</blockquote>");
404                     diffFile.println("<hr>");
405                     diffFile.println();
406                     
407                 } catch(IOException e) {
408                     System.out.println("IO Error while attempting to create " + fullDiffFileName);
409                     System.out.println("Error: " + e.getMessage());
410                     System.exit(1);
411                 }
412             } // if (currPkgName == null || currPkgName.compareTo(diffOutput.pkgName_) != 0)
413
// Now add the documentation difference text
414
diffFile.println(diffOutput.text_);
415             // Separate with a horizontal line
416
if (i != docDiffsArr.length - 1 &&
417                 diffOutput.className_ != null &&
418                 docDiffsArr[i+1].className_ != null &&
419                 diffOutput.className_.compareTo(docDiffsArr[i+1].className_) != 0)
420                 diffFile.println("<hr align=\"left\" width=\"100%\">");
421 // else
422
// diffFile.println("<hr align=\"left\" width=\"50%\">");
423
} // for (i = 0;
424
if (currPkgName != null)
425             closeDiffFile(); // Close the existing file
426

427         // Emit the single file which is the index to all documentation changes
428
emitDocDiffIndex(fullReportFileName, docDiffsArr);
429     }
430
431     /**
432      * Emit the single file which is the index to all documentation changes.
433      */

434     public static void emitDocDiffIndex(String JavaDoc fullReportFileName,
435                                         DiffOutput[] docDiffsArr) {
436
437         String JavaDoc fullDiffFileName = fullReportFileName +
438             JDiff.DIR_SEP + diffFileName + "index" +
439             HTMLReportGenerator.reportFileExt;
440
441         // Create the output file
442
try {
443             FileOutputStream fos = new FileOutputStream(fullDiffFileName);
444             diffFile = new PrintWriter(fos);
445             
446             // Write the HTML header
447
diffFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\"\"" + RootDocToXML.baseURI + "/TR/REC-html40/frameset.dtd\">");
448             diffFile.println("<HTML>");
449             diffFile.println("<HEAD>");
450             diffFile.println("<meta name=\"generator\" content=\"JDiff v" + JDiff.version + "\">");
451             diffFile.println("<!-- Generated by the JDiff Javadoc doclet -->");
452             diffFile.println("<!-- (" + JDiff.jDiffLocation + ") -->");
453 // diffFile.println("<!-- on " + new Date() + " -->");
454
diffFile.println("<meta name=\"description\" content=\"" + JDiff.jDiffDescription + "\">");
455             diffFile.println("<meta name=\"keywords\" content=\"" + JDiff.jDiffKeywords + "\">");
456             diffFile.println("<LINK REL=\"stylesheet\" TYPE=\"text/css\" HREF=\"" + "../" + "stylesheet-jdiff.css\" TITLE=\"Style\">");
457             diffFile.println("<TITLE>");
458             diffFile.println("All Documentation Differences");
459             diffFile.println("</TITLE>");
460             diffFile.println("</HEAD>");
461             diffFile.println("<BODY>");
462                         
463             // Write the navigation bar
464
diffFile.println("<!-- Start of nav bar -->");
465             diffFile.println("<TABLE summary=\"Navigation bar\" BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">");
466             diffFile.println("<TR>");
467             diffFile.println("<TD COLSPAN=2 BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\">");
468             diffFile.println(" <TABLE summary=\"Navigation bar\" BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"3\">");
469             diffFile.println(" <TR ALIGN=\"center\" VALIGN=\"top\">");
470             // Always have a link to the Javadoc files
471
diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + HTMLReportGenerator.newDocPrefix + "index.html\" target=\"_top\"><FONT CLASS=\"NavBarFont1\"><B><tt>" + APIDiff.newAPIName_ + "</tt></B></FONT></A>&nbsp;</TD>");
472             diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + HTMLReportGenerator.reportFileName + "-summary" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Overview</B></FONT></A>&nbsp;</TD>");
473             diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Package</FONT>&nbsp;</TD>");
474             diffFile.println(" <TD BGCOLOR=\"#FFFFFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Class</FONT>&nbsp;</TD>");
475             if (!Diff.noDocDiffs) {
476                 diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1Rev\"> <FONT CLASS=\"NavBarFont1Rev\"><B>Text Changes</B></FONT>&nbsp;</TD>");
477             }
478             if (HTMLReportGenerator.doStats) {
479                 diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_statistics" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Statistics</B></FONT></A>&nbsp;</TD>");
480             }
481             diffFile.println(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_help" + HTMLReportGenerator.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Help</B></FONT></A>&nbsp;</TD>");
482             diffFile.println(" </TR>");
483             diffFile.println(" </TABLE>");
484             diffFile.println("</TD>");
485             
486             // The right hand side title
487
diffFile.println("<TD ALIGN=\"right\" VALIGN=\"top\" ROWSPAN=3><EM><b>Generated by<br><a HREF=\"" + JDiff.jDiffLocation + "\" class=\"staysblack\" target=\"_top\">JDiff</a></b></EM></TD>");
488             diffFile.println("</TR>");
489             
490             // Links for frames and no frames
491
diffFile.println("<TR>");
492             diffFile.println(" <TD BGCOLOR=\"" + HTMLReportGenerator.bgcolor + "\" CLASS=\"NavBarCell2\"><FONT SIZE=\"-2\">");
493             diffFile.println(" <A HREF=\"" + "../" + HTMLReportGenerator.reportFileName + HTMLReportGenerator.reportFileExt + "\" TARGET=\"_top\"><B>FRAMES</B></A> &nbsp;");
494             diffFile.println(" &nbsp;<A HREF=\"" + diffFileName + "index" + HTMLReportGenerator.reportFileExt + "\" TARGET=\"_top\"><B>NO FRAMES</B></A></FONT></TD>");
495             diffFile.println(" <TD BGCOLOR=\"" + HTMLReportGenerator.bgcolor + "\" CLASS=\"NavBarCell2\">&nbsp;</TD>");
496             diffFile.println("</TR>");
497             
498             diffFile.println("</TABLE>");
499             diffFile.println("<HR>");
500             diffFile.println("<!-- End of nav bar -->");
501             
502             diffFile.println("<h2>");
503             diffFile.println("All Documentation Differences");
504             diffFile.println("</h2>");
505             diffFile.println();
506             
507             // For each package and class, add the first DiffOutput to
508
// the hash table. Used when generating navigation bars.
509
boolean firstPackage = true; // Set for the first package
510
boolean firstClass = true; // Set for first class in a package
511
boolean firstCtor = true; // Set for first ctor in a class
512
boolean firstMethod = true; // Set for first method in a class
513
boolean firstField = true; // Set for first field in a class
514
for (int i = 0; i < docDiffsArr.length; i++) {
515                 DiffOutput diffOutput = docDiffsArr[i];
516                 String JavaDoc link = "<a HREF=\"" + Diff.diffFileName + diffOutput.pkgName_ + HTMLReportGenerator.reportFileExt + "#" + diffOutput.id_ + "\">";
517
518                 // See if the package name changed
519
if (firstPackage || diffOutput.pkgName_.compareTo(docDiffsArr[i-1].pkgName_) != 0) {
520                     if (firstPackage) {
521                         firstPackage = false;
522                     } else {
523                         diffFile.println("<br>");
524                     }
525                     firstClass = true;
526                     firstCtor = true;
527                     firstMethod = true;
528                     firstField = true;
529                     String JavaDoc id = diffOutput.pkgName_ + "!package";
530                     firstDiffOutput.put(id, id);
531                     if (diffOutput.className_ == null) {
532                         diffFile.println("<A NAME=\"" + id + "\"></A>" + link + "Package <b>" + diffOutput.pkgName_ + "</b></a><br>");
533                     } else {
534                         diffFile.println("<A NAME=\"" + id + "\"></A>" + "Package <b>" + diffOutput.pkgName_ + "</b><br>");
535                     }
536                 }
537                 // See if the class name changed
538
if (diffOutput.className_ != null &&
539                     (firstClass ||
540                      diffOutput.className_.compareTo(docDiffsArr[i-1].className_) != 0)) {
541                     if (firstClass) {
542                         firstClass = false;
543                     } else {
544                         diffFile.println("<br>");
545                     }
546                     firstCtor = true;
547                     firstMethod = true;
548                     firstField = true;
549                     String JavaDoc id = diffOutput.pkgName_ + "." + diffOutput.className_ + "!class";
550                     firstDiffOutput.put(id, id);
551                     if (diffOutput.id_.endsWith("!class")) {
552                         diffFile.println("<A NAME=\"" + id + "\"></A>&nbsp;&nbsp;Class " + link + diffOutput.className_ + "</a><br>");
553                     } else {
554                         diffFile.println("<A NAME=\"" + id + "\"></A>&nbsp;&nbsp;Class " + diffOutput.className_ + "<br>");
555                     }
556                 }
557                 // Work out what kind of member this is, and
558
// display it appropriately
559
if (diffOutput.className_ != null &&
560                     !diffOutput.id_.endsWith("!class")) {
561                     int ctorIdx = diffOutput.id_.indexOf(".ctor");
562                     if (ctorIdx != -1) {
563                         diffFile.println("&nbsp;&nbsp;&nbsp;&nbsp;" + link + diffOutput.className_ + diffOutput.id_.substring(ctorIdx + 5) + "</a><br>");
564                     } else {
565                         int methodIdx = diffOutput.id_.indexOf(".dmethod.");
566                         if (methodIdx != -1) {
567                             diffFile.println("&nbsp;&nbsp;&nbsp;&nbsp;" + "Method " + link + diffOutput.id_.substring(methodIdx + 9) + "</a><br>");
568                         } else {
569                             int fieldIdx = diffOutput.id_.indexOf(".field.");
570                             if (fieldIdx != -1) {
571                                 diffFile.println("&nbsp;&nbsp;&nbsp;&nbsp;" + "Field " + link + diffOutput.id_.substring(fieldIdx + 7) + "</a><br>");
572                             }
573                         } //if (methodIdx != -1)
574
} //if (ctorIdx != -1)
575
} //diffOutput.className_ != null
576
}
577         } catch(IOException e) {
578             System.out.println("IO Error while attempting to create " + fullDiffFileName);
579             System.out.println("Error: " + e.getMessage());
580             System.exit(1);
581         }
582         closeDiffFile();
583     }
584
585     /**
586      * Emit the HTML footer and close the diff file.
587      */

588     public static void closeDiffFile() {
589         if (diffFile != null) {
590             // Write the HTML footer
591
diffFile.println();
592             diffFile.println("</BODY>");
593             diffFile.println("</HTML>");
594             diffFile.close();
595         }
596     }
597
598     /**
599      * Current file where documentation differences are written as colored
600      * differences.
601      */

602     public static PrintWriter diffFile = null;
603
604     /**
605      * Base name of the current file where documentation differences are
606      * written as colored differences.
607      */

608     public static String JavaDoc diffFileName = "docdiffs_";
609
610     /**
611      * The name of the current package, used to create diffFileName.
612      */

613     private static String JavaDoc currPkgName = null;
614
615     /**
616      * If set, then do not generate colored diffs for documentation.
617      * Default is true.
618      */

619     public static boolean noDocDiffs = true;
620
621     /**
622      * Define the type of emphasis for deleted words.
623      * 0 strikes the words through.
624      * 1 outlines the words in light grey.
625      */

626     public static int deleteEffect = 0;
627
628     /**
629      * Define the type of emphasis for inserted words.
630      * 0 colors the words red.
631      * 1 outlines the words in yellow, like a highlighter.
632      */

633     public static int insertEffect = 1;
634
635     /**
636      * For each package and class, the first DiffOutput is added to
637      * this hash table. Used when generating navigation bars.
638      */

639     public static Hashtable firstDiffOutput = new Hashtable();
640
641     /**
642      * If set, then show changes in implementation-related modifiers such as
643      * native and synchronized. For more information, see
644      * http://java.sun.com/j2se/1.4.1/docs/tooldocs/solaris/javadoc.html#generatedapideclarations
645      */

646     public static boolean showAllChanges = false;
647
648     /** The list of documentation differences. */
649     private static List docDiffs = new ArrayList(); // DiffOutput[]
650

651     /** Set to enable increased logging verbosity for debugging. */
652     private static boolean trace = false;
653         
654 }
655
Popular Tags