1 package jdiff; 2 3 import java.util.*; 4 import java.io.*; 5 6 13 public class HTMLIndexes { 14 15 16 public HTMLIndexes(HTMLReportGenerator h) { 17 h_ = h; 18 } 19 20 21 private HTMLReportGenerator h_ = null; 22 23 24 public void emitAllBottomLeftFiles(String packagesIndexName, 25 String classesIndexName, 26 String constructorsIndexName, 27 String methodsIndexName, 28 String fieldsIndexName, 29 String allDiffsIndexName, 30 APIDiff apiDiff) { 31 32 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 emitBottomLeftFile(allDiffsIndexName, apiDiff, 3, "All"); 44 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 68 public void emitBottomLeftFile(String indexBaseName, 69 APIDiff apiDiff, int indexType, 70 String programElementType) { 71 String filename = indexBaseName; 72 try { 73 String 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 128 private void generateLetterIndex(List list, char currChar, boolean larger) { 129 if (larger) 130 return; 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 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 164 private void emitIndexHeader(String indexName, int indexType, 165 boolean hasRemovals, 166 boolean hasAdditions, boolean hasChanges) { 167 String 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>"); 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 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> is New, <strike>strike</strike> is deleted</font>"); 235 h_.writeText(" </td>"); 236 h_.writeText(" </tr>"); 237 h_.writeText("</table><br>"); 238 } 239 240 241 public void emitPackagesIndex(APIDiff apiDiff, int indexType) { 242 packageNames = new ArrayList(); 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 273 emitIndexHeader("Packages", indexType, hasRemovals, hasAdditions, hasChanges); 275 276 h_.writeText("<br>"); 278 279 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 292 public char emitPackageIndexEntry(Index pkg, char oldsw) { 293 char res = oldsw; 294 char sw = pkg.name_.charAt(0); 296 if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) { 297 res = sw; 299 h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>"); 301 } 302 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 317 public void emitIndexEntries(Iterator iter) { 318 char oldsw = '\0'; 319 int multipleMarker = 0; 320 Index currIndex = null; while (iter.hasNext()) { 322 Index nextIndex = (Index)(iter.next()); 324 if (currIndex == null) { 325 currIndex = nextIndex; } else { 327 if (nextIndex.name_.compareTo(currIndex.name_) == 0) { 328 if (multipleMarker == 0) 331 multipleMarker = 1; else if (multipleMarker == 1) 333 multipleMarker = 2; oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker); 335 } else { 336 if (multipleMarker == 1) 337 multipleMarker = 2; oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker); 339 multipleMarker = 0; } 341 currIndex = nextIndex; 342 } 343 } 344 if (multipleMarker == 1) 346 multipleMarker = 2; if (currIndex != null) 348 oldsw = emitIndexEntry(currIndex, oldsw, multipleMarker); 349 } 350 351 355 public static boolean logMissingSinces = true; 356 357 358 public static PrintWriter missingSincesFile = null; 359 360 364 public void emitMissingSinces(Iterator iter) { 365 if (missingSincesFile == null) { 368 String 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 if (currIndex.changeType_ != 1) 382 continue; 383 String programElementType = currIndex.ename_; 384 String 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 424 public char emitIndexEntry(Index currIndex, char oldsw, int multipleMarker) { 425 String 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 442 public void emitClassesIndex(APIDiff apiDiff, int indexType) { 443 classNames = new ArrayList(); 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 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_; 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 485 public char emitClassIndexEntry(Index cls, char oldsw, 486 int multipleMarker) { 487 char res = oldsw; 488 String className = cls.pkgName_ + "." + cls.name_; 489 String classRef = cls.pkgName_ + "." + cls.name_; 490 boolean isInterface = cls.isInterface_; 491 char sw = cls.name_.charAt(0); 493 if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) { 494 res = sw; 495 h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>"); 497 if (sw == '_') 498 h_.writeText("<br><b>underscore</b> "); 499 else 500 h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font> "); 501 generateLetterIndex(classNames, sw, false); 502 } 503 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 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 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 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 538 public void emitConstructorsIndex(APIDiff apiDiff, int indexType) { 539 ctorNames = new ArrayList(); 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 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 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_; 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 586 public char emitCtorIndexEntry(Index ctor, char oldsw, int multipleMarker) { 587 char res = oldsw; 588 String className = ctor.pkgName_ + "." + ctor.name_; 589 String memberRef = ctor.pkgName_ + "." + ctor.name_; 590 String type = ctor.type_; 591 if (type.compareTo("void") == 0) 592 type = ""; 593 String shownType = HTMLReportGenerator.simpleName(type); 594 char sw = ctor.name_.charAt(0); 596 if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) { 597 res = sw; 598 h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>"); 600 if (sw == '_') 601 h_.writeText("<br><b>underscore</b> "); 602 else 603 h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font> "); 604 generateLetterIndex(ctorNames, sw, false); 605 } 606 if (multipleMarker == 1) { 608 h_.writeText("<i>" + ctor.name_ + "</i><br>"); 609 } 610 if (multipleMarker != 0) 611 h_.indent(INDENT_SIZE); 612 if (ctor.changeType_ == 0) { 616 String 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> constructor<br>"); 620 } else if (ctor.changeType_ == 1) { 621 String 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> constructor<br>"); 625 } else if (ctor.changeType_ == 2) { 626 String 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> constructor<br>"); 630 } 631 return res; 632 } 633 634 637 public void emitMethodsIndex(APIDiff apiDiff, int indexType) { 638 methNames = new ArrayList(); 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 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 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_; 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 685 public char emitMethodIndexEntry(Index meth, char oldsw, 686 int multipleMarker) { 687 char res = oldsw; 688 String className = meth.pkgName_ + "." + meth.className_; 689 String memberRef = meth.pkgName_ + "." + meth.className_; 690 String type = meth.type_; 691 if (type.compareTo("void") == 0) 692 type = ""; 693 String shownType = HTMLReportGenerator.simpleName(type); 694 char sw = meth.name_.charAt(0); 696 if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) { 697 res = sw; 698 h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>"); 700 if (sw == '_') 701 h_.writeText("<br><b>underscore</b> "); 702 else 703 h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font> "); 704 generateLetterIndex(methNames, sw, false); 705 } 706 if (multipleMarker == 1) { 708 h_.writeText("<i>" + meth.name_ + "</i><br>"); 709 } 710 if (multipleMarker != 0) 711 h_.indent(INDENT_SIZE); 712 if (meth.changeType_ == 0) { 714 String 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 <strike>"); 720 h_.emitTypeWithParens(shownType, false); 721 h_.writeText("</strike> in " + className); 722 } 723 h_.writeText("</A></nobr><br>"); 724 } else if (meth.changeType_ == 1) { 725 String 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 <b>"); 731 h_.emitTypeWithParens(shownType, false); 732 h_.writeText("</b> in " + className); 733 } 734 h_.writeText("</A></nobr><br>"); 735 } else if (meth.changeType_ == 2) { 736 String 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 "); 742 h_.emitTypeWithParens(shownType, false); 743 h_.writeText(" in " + className); 744 } 745 h_.writeText("</A></nobr><br>"); 746 } 747 return res; 748 } 749 750 753 public void emitFieldsIndex(APIDiff apiDiff, int indexType) { 754 fieldNames = new ArrayList(); 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 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 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_; 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 801 public char emitFieldIndexEntry(Index fld, char oldsw, 802 int multipleMarker) { 803 char res = oldsw; 804 String className = fld.pkgName_ + "." + fld.className_; 805 String memberRef = fld.pkgName_ + "." + fld.className_; 806 String type = fld.type_; 807 if (type.compareTo("void") == 0) 808 type = ""; 809 String shownType = HTMLReportGenerator.simpleName(type); 810 char sw = fld.name_.charAt(0); 812 if (Character.toUpperCase(sw) != Character.toUpperCase(oldsw)) { 813 res = sw; 814 h_.writeText("<A NAME=\"" + Character.toUpperCase(res) + "\"></A>"); 816 if (sw == '_') 817 h_.writeText("<br><b>underscore</b> "); 818 else 819 h_.writeText("<br><font size=\"+2\">" + Character.toUpperCase(sw) + "</font> "); 820 generateLetterIndex(fieldNames, sw, false); 821 } 822 if (multipleMarker == 1) { 824 h_.writeText("<i>" + fld.name_ + "</i><br>"); 825 } 826 if (multipleMarker != 0) { 827 h_.writeText(" in "); 829 } 830 if (fld.changeType_ == 0) { 832 String 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 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 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 867 public void emitAllDiffsIndex(APIDiff apiDiff, int indexType) { 868 allNames = new ArrayList(); allNames.addAll(packageNames); 872 allNames.addAll(classNames); 873 allNames.addAll(ctorNames); 874 allNames.addAll(methNames); 875 allNames.addAll(fieldNames); 876 Collections.sort(allNames); 878 879 emitIndexHeader("All Differences", indexType, atLeastOneRemoval, 880 atLeastOneAddition, atLeastOneChange); 881 882 isAllNames = true; 885 886 Iterator iter = allNames.iterator(); 889 char oldsw = '\0'; 890 int multipleMarker = 0; 891 Index currIndex = null; while (iter.hasNext()) { 893 Index nextIndex = (Index)(iter.next()); 895 if (currIndex == null) { 896 currIndex = nextIndex; } else { 898 if (nextIndex.name_.compareTo(currIndex.name_) == 0) { 899 if (multipleMarker == 0) 902 multipleMarker = 1; else if (multipleMarker == 1) 904 multipleMarker = 2; oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker); 906 } else { 907 if (multipleMarker == 1) 908 multipleMarker = 2; oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker); 910 multipleMarker = 0; } 912 currIndex = nextIndex; 913 } 914 } 915 if (multipleMarker == 1) 917 multipleMarker = 2; if (currIndex != null) 919 oldsw = emitIndexEntryForAny(currIndex, oldsw, multipleMarker); 920 921 isAllNames = false; 924 } 925 926 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 949 private List allNames = null; 951 952 private List packageNames = null; 954 955 private List classNames = null; 957 958 private List ctorNames = null; 960 961 private List methNames = null; 963 964 private List fieldNames = null; 966 967 private boolean isAllNames = false; 968 969 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 985 private boolean atLeastOneRemoval = false; 986 987 988 private boolean atLeastOneAddition = false; 989 990 991 private boolean atLeastOneChange = false; 992 993 997 private final int INDENT_SIZE = 2; 998 } 999 1000 1006class Index implements Comparable { 1007 1008 1009 public String ename_ = null; 1010 1011 1012 public String name_ = null; 1013 1014 1015 public int changeType_; 1016 1017 1018 public String pkgName_ = null; 1019 1020 1021 public boolean isInterface_= false; 1022 1023 1024 public String doc_ = null; 1025 1026 1029 public String type_ = null; 1030 1031 1034 public String className_ = null; 1035 1036 1037 public Index(String name, int changeType) { 1038 ename_ = "package"; 1039 name_ = name; 1040 changeType_ = changeType; 1041 } 1042 1043 1044 public Index(String name, int changeType, String pkgName, boolean isInterface) { 1045 ename_ = "class"; 1046 name_ = name; 1047 changeType_ = changeType; 1048 pkgName_ = pkgName; 1049 isInterface_ = isInterface; 1050 } 1051 1052 1053 public Index(String name, int changeType, String pkgName, String type) { 1054 ename_ = "constructor"; 1055 name_ = name; 1056 changeType_ = changeType; 1057 pkgName_ = pkgName; 1058 type_ = type; 1059 } 1060 1061 1062 public Index(String name, int changeType, String pkgName, 1063 String className, String type) { 1064 ename_ = "method"; 1065 name_ = name; 1066 changeType_ = changeType; 1067 pkgName_ = pkgName; 1068 className_ = className; 1069 type_ = type; 1070 } 1071 1072 1078 public Index(String name, int changeType, String pkgName, 1079 String className, String 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 1090 public int compareTo(Object o) { 1091 return name_.compareToIgnoreCase(((Index)o).name_); 1092 } 1093 1094} 1095 1096 | Popular Tags |