1 package jdiff; 2 3 import java.util.*; 4 import java.io.*; 5 6 /** 7 * Emit HTML files for the supporting infrastructure for the HTML report. 8 * Examples are stylesheets, help files, frame files. 9 * 10 * See the file LICENSE.txt for copyright details. 11 * @author Matthew Doar, mdoar@pobox.com 12 */ 13 public class HTMLFiles { 14 15 /** Constructor. */ HTMLFiles(HTMLReportGenerator h)16 public HTMLFiles(HTMLReportGenerator h) { 17 h_ = h; 18 } 19 20 /** The HTMLReportGenerator instance used to write HTML. */ 21 private HTMLReportGenerator h_ = null; 22 23 /** 24 * Emit the top-level changes.html frames file where everything starts. 25 */ emitTopLevelFile(String tln, APIDiff apiDiff)26 public void emitTopLevelFile(String tln, 27 APIDiff apiDiff) { 28 try { 29 FileOutputStream fos = new FileOutputStream(tln); 30 h_.reportFile = new PrintWriter(fos); 31 // Write out the HTML header 32 h_.writeStartHTMLHeaderWithDate(); 33 // Write out the title 34 String oldAPIName = "Old API"; 35 if (apiDiff.oldAPIName_ != null) 36 oldAPIName = apiDiff.oldAPIName_; 37 String newAPIName = "New API"; 38 if (apiDiff.newAPIName_ != null) 39 newAPIName = apiDiff.newAPIName_; 40 if (h_.windowTitle == null) 41 h_.writeHTMLTitle("API Differences between " + oldAPIName + " and " + newAPIName); 42 else 43 h_.writeHTMLTitle(h_.windowTitle); 44 // Note that the stylesheet is in the same directory 45 h_.writeStyleSheetRef(true); 46 h_.writeText("</head>"); 47 // Note that the top-level frame file doesn't have the BODY tag 48 h_.writeText("<frameset cols=\"242,**\" framespacing=\"1\" frameborder=\"yes\" border=\"1\" bordercolor=\"#e9e9e9\"> "); 49 h_.writeText("<frameset rows=\"174,**\" framespacing=\"1\" frameborder=\"yes\" border=\"1\" bordercolor=\"#e9e9e9\">"); 50 51 // Convert filenames to web links 52 String tlfLink = h_.reportFileName + "/jdiff_topleftframe" + h_.reportFileExt; 53 String allDiffsLink = h_.reportFileName + "/alldiffs_index_all" + h_.reportFileExt; 54 String csnLink = h_.reportFileName + "/" + h_.reportFileName + "-summary" + h_.reportFileExt; 55 56 h_.writeText(" <frame src=\"" + tlfLink + "\" scrolling=\"no\" name=\"topleftframe\" frameborder=\"1\">"); 57 h_.writeText(" <frame src=\"" + allDiffsLink + "\" scrolling=\"auto\" name=\"bottomleftframe\" frameborder=\"1\">"); 58 h_.writeText(" </frameset>"); 59 h_.writeText(" <frame src=\"" + csnLink + "\" scrolling=\"auto\" name=\"rightframe\" frameborder=\"1\">"); 60 h_.writeText("</frameset>"); 61 h_.writeText("<noframes>"); 62 h_.writeText("<h2>"); 63 h_.writeText("Frame Alert"); 64 h_.writeText("</h2>\n"); 65 h_.writeText("<p>"); 66 h_.writeText("This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client."); 67 h_.writeText("<br>"); 68 h_.writeText("Link to <a href=\"" + csnLink + "\" target=\"_top\">Non-frame version.</A>"); 69 h_.writeText("</noframes>"); 70 h_.writeText("</html>"); 71 h_.reportFile.close(); 72 } catch(IOException e) { 73 System.out.println("IO Error while attempting to create " + tln); 74 System.out.println("Error: " + e.getMessage()); 75 System.exit(1); 76 } 77 } 78 79 /** Emit a frame with all the links to the index files. */ emitTopLeftFile(String tlf)80 public void emitTopLeftFile(String tlf) { 81 try { 82 FileOutputStream fos = new FileOutputStream(tlf); 83 h_.reportFile = new PrintWriter(fos); 84 h_.writeStartHTMLHeader(); 85 h_.writeHTMLTitle("Android API Version Differences"); 86 h_.writeStyleSheetRef(); 87 h_.writeText("</HEAD>"); 88 h_.writeText("<BODY class=\"gc-documentation\" style=\"padding:12px;\">"); 89 90 h_.writeText("<table class=\"jdiffIndex\" summary=\"Links to diff index files\" BORDER=\"0\" WIDTH=\"100%\" cellspacing=\"0\" cellpadding=\"0\" style=\"margin:0\">"); 91 h_.writeText("<TR>"); 92 h_.writeText(" <th class=\"indexHeader\" nowrap>"); 93 h_.writeText(" Select a Diffs Index:</th>"); 94 h_.writeText("</TR>"); 95 h_.writeText("<TR>"); 96 h_.writeText(" <TD><FONT CLASS=\"indexText\" size=\"-2\"><A HREF=\"alldiffs_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">All Differences</A></FONT><br></TD>"); 97 h_.writeText("</TR>"); 98 h_.writeText("<TR>"); 99 h_.writeText(" <TD NOWRAP><FONT CLASS=\"indexText\" size=\"-2\"><A HREF=\"packages_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">By Package</A></FONT><br></TD>"); 100 h_.writeText("</TR>"); 101 h_.writeText("<TR>"); 102 h_.writeText(" <TD NOWRAP><FONT CLASS=\"indexText\" size=\"-2\"><A HREF=\"classes_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">By Class</A></FONT><br></TD>"); 103 h_.writeText("</TR>"); 104 h_.writeText("<TR>"); 105 h_.writeText(" <TD NOWRAP><FONT CLASS=\"indexText\" size=\"-2\"><A HREF=\"constructors_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">By Constructor</A></FONT><br></TD>"); 106 h_.writeText("</TR>"); 107 h_.writeText("<TR>"); 108 h_.writeText(" <TD NOWRAP><FONT CLASS=\"indexText\" size=\"-2\"><A HREF=\"methods_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">By Method</A></FONT><br></TD>"); 109 h_.writeText("</TR>"); 110 h_.writeText("<TR>"); 111 h_.writeText(" <TD NOWRAP><FONT CLASS=\"indexText\" size=\"-2\"><A HREF=\"fields_index_all" + h_.reportFileExt + "\" TARGET=\"bottomleftframe\">By Field</A></FONT><br></TD>"); 112 h_.writeText("</TR>"); 113 h_.writeText("</TABLE>"); 114 115 h_.writeHTMLFooter(); 116 h_.reportFile.close(); 117 } catch(IOException e) { 118 System.out.println("IO Error while attempting to create " + tlf); 119 System.out.println("Error: " + e.getMessage()); 120 System.exit(1); 121 } 122 } 123 124 /** Emit the help file. */ emitHelp(String fullReportFileName, APIDiff apiDiff)125 public void emitHelp(String fullReportFileName, APIDiff apiDiff) { 126 String helpFileName = fullReportFileName + JDiff.DIR_SEP + "jdiff_help" + h_.reportFileExt; 127 try { 128 FileOutputStream fos = new FileOutputStream(helpFileName); 129 h_.reportFile = new PrintWriter(fos); 130 h_.writeStartHTMLHeader(); 131 h_.writeHTMLTitle("JDiff Help"); 132 h_.writeStyleSheetRef(); 133 h_.writeText("</HEAD>"); 134 h_.writeText("<BODY>"); 135 // Write a customized navigation bar for the help page 136 h_.writeText("<!-- Start of nav bar -->"); 137 h_.writeText("<TABLE summary=\"Navigation bar\" BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">"); 138 h_.writeText("<TR>"); 139 h_.writeText("<TD COLSPAN=2 BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\">"); 140 h_.writeText(" <TABLE summary=\"Navigation bar\" BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"3\">"); 141 h_.writeText(" <TR ALIGN=\"center\" VALIGN=\"top\">"); 142 // Always have a link to the Javadoc files 143 h_.writeText(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + h_.newDocPrefix + "index.html\" target=\"_top\"><FONT CLASS=\"NavBarFont1\"><B><code>" + apiDiff.newAPIName_ + "</code></B></FONT></A> </TD>"); 144 h_.writeText(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + h_.reportFileName + "-summary" + h_.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Overview</B></FONT></A> </TD>"); 145 h_.writeText(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <FONT CLASS=\"NavBarFont1\">Package</FONT> </TD>"); 146 h_.writeText(" <TD BGCOLOR=\"#FFFFFF\" CLASS=\"NavBarCell1\"> <FONT CLASS=\"NavBarFont1\">Class</FONT> </TD>"); 147 if (!Diff.noDocDiffs) { 148 h_.writeText(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + Diff.diffFileName + "index" + h_.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Text Changes</B></FONT></A> </TD>"); 149 } 150 if (h_.doStats) { 151 h_.writeText(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"jdiff_statistics" + h_.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Statistics</B></FONT></A> </TD>"); 152 } 153 h_.writeText(" <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1Rev\"> <FONT CLASS=\"NavBarFont1Rev\"><B>Help</B></FONT> </TD>"); 154 h_.writeText(" </TR>"); 155 h_.writeText(" </TABLE>"); 156 h_.writeText("</TD>"); 157 158 // The right hand side title 159 h_.writeText("<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>"); 160 h_.writeText("</TR>"); 161 162 // Links for frames and no frames 163 h_.writeText("<TR>"); 164 h_.writeText(" <TD BGCOLOR=\"" + h_.bgcolor + "\" CLASS=\"NavBarCell2\"><FONT SIZE=\"-2\"></FONT>"); 165 h_.writeText("</TD>"); 166 h_.writeText(" <TD BGCOLOR=\"" + h_.bgcolor + "\" CLASS=\"NavBarCell2\"><FONT SIZE=\"-2\">"); 167 h_.writeText(" <A HREF=\"" + "../" + h_.reportFileName + h_.reportFileExt + "\" TARGET=\"_top\"><B>FRAMES</B></A> "); 168 h_.writeText(" <A HREF=\"jdiff_help" + h_.reportFileExt + "\" TARGET=\"_top\"><B>NO FRAMES</B></A></FONT></TD>"); 169 h_.writeText("</TR>"); 170 171 h_.writeText("</TABLE>"); 172 h_.writeText("<HR>"); 173 h_.writeText ("<!-- End of nav bar -->"); 174 175 h_.writeText("<center>"); 176 h_.writeText("<H1>JDiff Documentation</H1>"); 177 h_.writeText("</center>"); 178 179 h_.writeText("<BLOCKQUOTE>"); 180 h_.writeText("JDiff is a <a href=\"https://java.sun.com/j2se/javadoc/\" target=\"_top\">Javadoc</a> doclet which generates a report of the API differences between two versions of a product. It does not report changes in Javadoc comments, or changes in what a class or method does. "); 181 h_.writeText("This help page describes the different parts of the output from JDiff."); 182 h_.writeText("</BLOCKQUOTE>"); 183 184 h_.writeText("<BLOCKQUOTE>"); 185 h_.writeText(" See the reference page in the <a href=\"" + JDiff.jDiffLocation + "\">source for JDiff</a> for information about how to generate a report like this one."); 186 h_.writeText("</BLOCKQUOTE>"); 187 188 h_.writeText("<BLOCKQUOTE>"); 189 h_.writeText("The indexes shown in the top-left frame help show each type of change in more detail. The index \"All Differences\" contains all the differences between the APIs, in alphabetical order. "); 190 h_.writeText("These indexes all use the same format:"); 191 h_.writeText("<ul>"); 192 h_.writeText("<li>Removed packages, classes, constructors, methods and fields are <strike>struck through</strike>.</li>"); 193 h_.writeText("<li>Added packages, classes, constructors, methods and fields appear in <b>bold</b>.</li>"); 194 h_.writeText("<li>Changed packages, classes, constructors, methods and fields appear in normal text.</li>"); 195 h_.writeText("</ul>"); 196 h_.writeText("</BLOCKQUOTE>"); 197 198 h_.writeText("<BLOCKQUOTE>"); 199 h_.writeText("You can always tell when you are reading a JDiff page, rather than a Javadoc page, by the color of the index bar and the color of the background. "); 200 h_.writeText("Links which take you to a Javadoc page are always in a <code>typewriter</code> font. "); 201 h_.writeText("Just like Javadoc, all interface names are in <i>italic</i>, and class names are not italicized. Where there are multiple entries in an index with the same name, the heading for them is also in italics, but is not a link."); 202 h_.writeText("</BLOCKQUOTE>"); 203 204 h_.writeText("<BLOCKQUOTE>"); 205 h_.writeText("<H3><b><code>Javadoc</code></b></H3>"); 206 h_.writeText("This is a link to the <a href=\"" + h_.newDocPrefix + "index.html\" target=\"_top\">top-level</a> Javadoc page for the new version of the product."); 207 h_.writeText("</BLOCKQUOTE>"); 208 209 h_.writeText("<BLOCKQUOTE>"); 210 h_.writeText("<H3>Overview</H3>"); 211 h_.writeText("The <a href=\"" + h_.reportFileName + "-summary" + 212 h_.reportFileExt + "\">overview</a> is the top-level summary of what was removed, added and changed between versions."); 213 h_.writeText("</BLOCKQUOTE>"); 214 215 h_.writeText("<BLOCKQUOTE>"); 216 h_.writeText("<H3>Package</H3>"); 217 h_.writeText("This is a link to the package containing the current changed class or interface."); 218 h_.writeText("</BLOCKQUOTE>"); 219 220 h_.writeText("<BLOCKQUOTE>"); 221 h_.writeText("<H3>Class</H3>"); 222 h_.writeText("This is highlighted when you are looking at the changed class or interface."); 223 h_.writeText("</BLOCKQUOTE>"); 224 225 h_.writeText("<BLOCKQUOTE>"); 226 h_.writeText("<H3>Text Changes</H3>"); 227 h_.writeText("This is a link to the top-level index of all documentation changes for the current package or class. "); 228 h_.writeText("If it is not present, then there are no documentation changes for the current package or class. "); 229 h_.writeText("This link can be removed entirely by not using the <code>-docchanges</code> option."); 230 h_.writeText("</BLOCKQUOTE>"); 231 232 h_.writeText("<BLOCKQUOTE>"); 233 h_.writeText("<H3>Statistics</H3>"); 234 h_.writeText("This is a link to a page which shows statistics about the changes between the two APIs."); 235 h_.writeText("This link can be removed entirely by not using the <code>-stats</code> option."); 236 h_.writeText("</BLOCKQUOTE>"); 237 238 h_.writeText("<BLOCKQUOTE>"); 239 h_.writeText("<H3>Help</H3>"); 240 h_.writeText("A link to this Help page for JDiff."); 241 h_.writeText("</BLOCKQUOTE>"); 242 243 h_.writeText("<BLOCKQUOTE>"); 244 h_.writeText("<H3>Prev/Next</H3>"); 245 h_.writeText("These links take you to the previous and next changed package or class."); 246 h_.writeText("</BLOCKQUOTE>"); 247 248 h_.writeText("<BLOCKQUOTE>"); 249 h_.writeText("<H3>Frames/No Frames</H3>"); 250 h_.writeText("These links show and hide the HTML frames. All pages are available with or without frames."); 251 h_.writeText("</BLOCKQUOTE>"); 252 253 h_.writeText("<BLOCKQUOTE>"); 254 h_.writeText("<H2>Complex Changes</H2>"); 255 h_.writeText("There are some complex changes which can occur between versions, for example, when two or more methods with the same name change simultaneously, or when a method or field is moved into or from a superclass. "); 256 h_.writeText("In these cases, the change will be seen as a removal and an addition, rather than as a change. Unexpected removals or additions are often part of one of these type of changes. "); 257 h_.writeText("</BLOCKQUOTE>"); 258 259 h_.writeHTMLFooter(); 260 h_.reportFile.close(); 261 } catch(IOException e) { 262 System.out.println("IO Error while attempting to create " + helpFileName); 263 System.out.println("Error: " + e.getMessage()); 264 System.exit(1); 265 } 266 } 267 268 /** Emit the external stylesheet file. */ emitStylesheet()269 public void emitStylesheet() { 270 String stylesheetFileName = "stylesheet-jdiff.css"; 271 if (h_.outputDir != null) 272 stylesheetFileName = h_.outputDir + JDiff.DIR_SEP + stylesheetFileName; 273 try { 274 FileOutputStream fos = new FileOutputStream(stylesheetFileName); 275 h_.reportFile = new PrintWriter(fos); 276 h_.writeText(); 277 h_.writeText("/* (" + JDiff.jDiffLocation + ") */"); 278 //h_.writeText("/* on " + new Date() + " */"); 279 h_.writeText(); 280 281 h_.writeText("div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;}"); 282 h_.writeText("table.diffspectable {border:1px;padding:0px;margin:0px;}"); 283 h_.writeText(".diffspechead {background-color:#eee;}"); 284 h_.writeText(".diffspectable tr {border:0px;padding:0px;}"); 285 h_.writeText(".diffspectable td {background-color:eee;border:0px;font-size:90%;font-weight:normal;padding:0px;padding-left:1px;padding-right:1px;text-align:center;color:777;}"); 286 h_.writeText("td.diffvalueold {color:orange;background-color:white;border:0px;font-size:80%;font-style:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;}"); 287 h_.writeText("td.diffvaluenew {color:green;background-color:white;border:0px;font-size:80%;font-weight:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;}"); 288 h_.writeText("td.diffvalue {color:444;background-color:white;border:0px;font-size:80%;font-weight:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;}"); 289 h_.writeText("td.diffspec {background-color:white;border:0px;font-size:80%;font-weight:normal;padding:1px;color:444;text-align:right;padding-right:.5em;line-height:.95em;}"); 290 h_.writeText("tt {font-size:11pt;font-family:monospace;}"); 291 h_.writeText(".indexHeader {"); 292 h_.writeText(" font-size:96%;"); 293 h_.writeText(" line-height:.8em;}"); 294 295 h_.writeText(".jdiffIndex td {"); 296 h_.writeText(" font-size:96%;"); 297 h_.writeText(" xline-height:.8em;"); 298 h_.writeText(" padding:2px;"); 299 h_.writeText(" padding-left:1em;}"); 300 301 h_.writeText(".indexText {"); 302 h_.writeText(" font-size:100%;"); 303 h_.writeText(" padding-left:1em;}"); 304 305 h_.writeText("#indexTableCaption {"); 306 h_.writeText(" font-size:96%;"); 307 h_.writeText(" margin-top:.25em;"); 308 h_.writeText(" margin-bottom:0;"); 309 h_.writeText(" }"); 310 311 h_.writeText(".hiddenlink {"); 312 h_.writeText(" font-size:96%;"); 313 h_.writeText(" line-height:.8em;"); 314 h_.writeText(" text-decoration:none;}"); 315 316 h_.writeText("a {"); 317 h_.writeText(" text-decoration:none;}"); 318 319 h_.writeText("a:hover {"); 320 h_.writeText(" text-decoration:underline;}"); 321 322 h_.writeText(".indexBox {"); 323 h_.writeText(" border: 1px solid red;"); 324 h_.writeText(" margin:1em 0 0 0;}"); 325 326 h_.writeText(".letterIndexHead {"); 327 h_.writeText(" font-size: 1.5em;font-weight:9;"); 328 h_.writeText(" margin:0 0 0em 0;"); 329 h_.writeText(" border: 1px solid red;}"); 330 331 h_.reportFile.close(); 332 333 } catch(IOException e) { 334 System.out.println("IO Error while attempting to create " + stylesheetFileName); 335 System.out.println("Error: " + e.getMessage()); 336 System.exit(1); 337 } 338 } 339 340 } 341