1package jdiff;
2
3import java.util.*;
4import 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 */
13public class HTMLFiles {
14
15    /** Constructor. */
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     */
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=\"20%,80%\">");
49            h_.writeText("<frameset rows=\"196,**\">");
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\">");
57            h_.writeText("    <FRAME SRC=\"" + allDiffsLink + "\" SCROLLING=\"auto\" NAME=\"bottomleftframe\">");
58            h_.writeText("  </FRAMESET>");
59            h_.writeText("  <FRAME SRC=\"" + csnLink + "\" SCROLLING=\"auto\" NAME=\"rightframe\">");
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 top left frame with all the links to the index files. */
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 Diffs Index");
86            h_.writeStyleSheetRef();
87            h_.writeText("</HEAD>");
88            h_.writeText("<BODY>");
89
90            h_.writeText("<table summary=\"Links to all index files\" BORDER=\"0\" WIDTH=\"100%\" cellspacing=\"0\" cellpadding=\"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=\"-1\"><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=\"-1\"><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=\"-1\"><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=\"-1\"><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=\"-1\"><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=\"-1\"><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. */
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><tt>" + apiDiff.newAPIName_ + "</tt></B></FONT></A>&nbsp;</TD>");
144            h_.writeText("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> <A HREF=\"" + h_.reportFileName + "-summary" + h_.reportFileExt + "\"><FONT CLASS=\"NavBarFont1\"><B>Overview</B></FONT></A>&nbsp;</TD>");
145            h_.writeText("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Package</FONT>&nbsp;</TD>");
146            h_.writeText("      <TD BGCOLOR=\"#FFFFFF\" CLASS=\"NavBarCell1\"> &nbsp;<FONT CLASS=\"NavBarFont1\">Class</FONT>&nbsp;</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>&nbsp;</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>&nbsp;</TD>");
152            }
153            h_.writeText("      <TD BGCOLOR=\"#EEEEFF\" CLASS=\"NavBarCell1Rev\"> &nbsp;<FONT CLASS=\"NavBarFont1Rev\"><B>Help</B></FONT>&nbsp;</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>  &nbsp;");
168            h_.writeText("  &nbsp;<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=\"http://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 <tt>typewriter</tt> 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><tt>Javadoc</tt></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 CSS external stylesheet file. */
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            //h_.writeText("/* Define colors, fonts and other style attributes here to override the defaults  */");
281            //h_.writeText();
282            //h_.writeText("/* Page background color */");
283            //h_.writeText("body { background-color: " + h_.bgcolor + "; font-family: arial; }");
284            //First argument after backgroun: is for older Netscape browsers
285            //For more information, see http://css.nu/pointers/bugs.html and
286            //http://www.richinstyle.com/bugs/netscape4.html
287            //h_.writeText("body { background: #CCFFFF url(background.gif); font-family: arial; }");
288            //h_.writeText();
289            //h_.writeText("/* Table colors */");
290            //h_.writeText(".TableHeadingColor     { background: #CCCCFF } /* Dark mauve */");
291            //h_.writeText(".TableSubHeadingColor  { background: #EEEEFF } /* Light mauve */");
292            //h_.writeText(".TableRowColor         { background: #FFFFFF } /* White */");
293            //h_.writeText();
294            //h_.writeText("/* Font used in left-hand frame lists */");
295            //h_.writeText(".FrameTitleFont   { font-size: normal; font-family: normal }");
296            //h_.writeText(".FrameHeadingFont { font-size: normal; font-family: normal }");
297            //h_.writeText(".FrameItemFont    { font-size: normal; font-family: normal }");
298            //h_.writeText();
299            //h_.writeText("/* Example of smaller, sans-serif font in frames */");
300            //h_.writeText("/* .FrameItemFont  { font-size: 10pt; font-family: Helvetica, Arial, sans-serif } */");
301            //h_.writeText();
302            //h_.writeText("/* Navigation bar fonts and colors */");
303            //h_.writeText(".NavBarCell1    { background-color:#FFFFCC;} /* Changed to yellowish to make difference from Javadoc clear */");
304            //h_.writeText(".NavBarCell1Rev { background-color:#00008B;}/* Dark Blue */");
305            //h_.writeText(".NavBarFont1    { font-family: Arial, Helvetica, sans-serif; color:#000000;}");
306            //h_.writeText(".NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}");
307            //h_.writeText();
308            //h_.writeText(".NavBarCell2    { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}");
309            //h_.writeText(".NavBarCell3    { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}");
310            //h_.writeText();
311            h_.writeText("/* ");
312            h_.writeText(" Links which become blue when hovered upon and show that they have been ");
313            h_.writeText(" visited. ");
314            h_.writeText("*/");
315	    h_.writeText(".hiddenlink {text-decoration:none;}");
316            h_.writeText("a.hiddenlink:link      {color: black; text-decoration: none}");
317            h_.writeText("a.hiddenlink:visited   {color: purple; text-decoration: none}");
318            h_.writeText("a.hiddenlink:hover     {color: blue; text-decoration: underline;}");
319            h_.writeText();
320            h_.writeText("/* ");
321            h_.writeText(" Links which become blue when hovered upon but do not show that they have ");
322            h_.writeText(" been visited. ");
323            h_.writeText("*/");
324            h_.writeText("a.staysblack:link     {color: black; text-decoration: none}");
325            h_.writeText("a.staysblack:visited  {color: black; text-decoration: none}");
326            h_.writeText("a.staysblack:hover    {color: blue; text-decoration: underline;}");
327            h_.writeText("");
328            h_.writeText("div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;}");
329            h_.writeText("table.diffspectable {border:1px;padding:0px;margin:0px;}");
330            h_.writeText(".diffspectable tr {border:0px;padding:0px;}");
331            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;}");
332            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;}");
333            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;}");
334            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;}");
335            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;}");
336            h_.writeText("tt {font-size:11pt;font-family:monospace;}");
337            h_.writeText("code {font-size:11pt;font-family:monospace;}");
338            h_.writeText(".indexHeader {font-size:11pt;line-height:.8em;}");
339            h_.writeText(".indexText {font-size:9pt;line-height:.8em;padding-left:1em;}");
340
341            h_.writeText(".pagecontenth1 {");
342            h_.writeText("  line-height: 130%;");
343            h_.writeText("  font-size: 170%;");
344            h_.writeText("  xmargin: 0 0 0 -10px;");
345            h_.writeText("  padding: .8em 0 0;");
346            h_.writeText("  border: none;");
347            h_.writeText("  background: none;");
348            h_.writeText("}");
349            h_.writeText("");
350            h_.writeText(".pagecontenth2 {");
351            h_.writeText("  font-size: 130%;");
352            h_.writeText("  font-weight: bold;");
353            h_.writeText("  margin: 2em 0 0 -10px; ");
354            h_.writeText("  padding: 1px 3px;");
355            h_.writeText("  position: relative;");
356            h_.writeText("  border-top: 1px solid #3366CC;");
357            h_.writeText("  background-color: #e5ecf9;");
358            h_.writeText("}");
359            h_.reportFile.close();
360
361        } catch(IOException e) {
362            System.out.println("IO Error while attempting to create " + stylesheetFileName);
363            System.out.println("Error: " + e.getMessage());
364            System.exit(1);
365        }
366    }
367
368}
369