diff.jsp revision 1388
1281N/A<%--
1186N/A$Id$
1186N/A
0N/ACDDL HEADER START
0N/A
0N/AThe contents of this file are subject to the terms of the
1281N/ACommon Development and Distribution License (the "License").
0N/AYou may not use this file except in compliance with the License.
0N/A
0N/ASee LICENSE.txt included in this distribution for the specific
0N/Alanguage governing permissions and limitations under the License.
0N/A
0N/AWhen distributing Covered Code, include this CDDL HEADER in each
0N/Afile and include the License file at LICENSE.txt.
0N/AIf applicable, add the following below this CDDL HEADER, with the
0N/Afields enclosed by brackets "[]" replaced with your own identifying
0N/Ainformation: Portions Copyright [yyyy] [name of copyright owner]
0N/A
0N/ACDDL HEADER END
0N/A
830N/ACopyright 2009 Sun Microsystems, Inc. All rights reserved.
0N/AUse is subject to license terms.
0N/A
1186N/APortions Copyright 2011 Jens Elkner.
1186N/A--%><%@page import="
1186N/Ajava.io.BufferedReader,
1186N/Ajava.io.FileNotFoundException,
1186N/Ajava.io.InputStream,
1186N/Ajava.io.InputStreamReader,
1186N/Ajava.io.UnsupportedEncodingException,
1186N/Ajava.net.URLDecoder,
1186N/Ajava.util.ArrayList,
0N/A
1186N/Aorg.apache.commons.jrcs.diff.Chunk,
1186N/Aorg.apache.commons.jrcs.diff.Delta,
1186N/Aorg.apache.commons.jrcs.diff.Diff,
1186N/Aorg.apache.commons.jrcs.diff.Revision,
1186N/Aorg.opensolaris.opengrok.analysis.AnalyzerGuru,
0N/Aorg.opensolaris.opengrok.analysis.FileAnalyzer.Genre,
1186N/Aorg.opensolaris.opengrok.web.DiffData,
1186N/Aorg.opensolaris.opengrok.web.DiffType"
1186N/A%><%!
1388N/Aprivate static final String getAnnotateRevision(DiffData dd) {
1388N/A if (dd.type == DiffType.OLD || dd.type == DiffType.NEW) {
1388N/A return "<script type=\"text/javascript\">/* <![CDATA[ */ "
1388N/A + "O.rev='r=" + (dd.type == DiffType.NEW ? dd.rev2 : dd.rev1)
1388N/A + "'; /* ]]> */</script>";
1388N/A }
1388N/A return "";
1388N/A}
1388N/A
1388N/A/**
1388N/A * Dump unchanged lines of a file.
1388N/A * @param line the current line number (start of dump)
1388N/A * @param howMany number fo lines to dump.
1388N/A * @param trailing number of trailing lines to print after a "hidden" block
1388N/A * (leading is always 8).
1388N/A * @param file source code lines of the file to partially dump.
1388N/A * @param bn where to append the line numbers
1388N/A * @param bs where to append the source code lines
1388N/A * @param dd diff data needed to emit anchors for hidden blocks
1388N/A * @param a if {code true}, line numbers are get an anchor named with
1388N/A * the linenumber
1388N/A * @throws IndexOutOfBoundsException if <var>file</var> contains less than
1388N/A * <var>line</var> + <var>howMany</var> entries.
1388N/A */
1388N/Aprivate static final int dumpFile(int line, int howMany, int trailing,
1388N/A String[] file, StringBuilder bn, StringBuilder bs, DiffData dd, boolean a)
1388N/A{
1388N/A int max = line + howMany;
1388N/A if (dd.full || howMany < 20) {
1388N/A line++;
1388N/A for (;line <= max; line++) {
1388N/A if (a) {
1388N/A bn.append("<a name=\"").append(line).append("\">")
1388N/A .append(line).append("</a>\n");
1388N/A } else {
1388N/A bn.append(line).append('\n');
1388N/A }
1388N/A bs.append(Util.htmlize(file[line-1])).append('\n');
1388N/A }
1388N/A } else {
1388N/A // row n
1388N/A for (int j = line+1; j <= line + 8; j++) {
1388N/A if (a) {
1388N/A bn.append("<a name=\"").append(j).append("\">")
1388N/A .append(j).append("</a>\n");
1388N/A } else {
1388N/A bn.append(j).append('\n');
1388N/A }
1388N/A bs.append(Util.htmlize(file[j-1])).append('\n');
1388N/A }
1388N/A // should be row n+1
1388N/A String eol = trailing > 0 ? "---\n\n" : "---\n";
1388N/A bn.append('\n').append(eol);
1388N/A bs.append("\n<b> ").append(howMany - 8 - trailing)
1388N/A .append(" unchanged lines hidden</b> (<a href=\"")
1388N/A .append(dd.reqURI).append("?r1=").append(dd.rp1)
1388N/A .append("&amp;r2=").append(dd.rp2)
1388N/A .append("&amp;format=").append(dd.type.getAbbrev())
1388N/A .append("&amp;full=1#").append(line)
1388N/A .append("\">view full</a>) ").append(eol);
1388N/A line += howMany - trailing + 1;
1388N/A // should be row n+2
1388N/A for (; line <= max; line++) {
1388N/A if (a) {
1388N/A bn.append("<a name=\"").append(line).append("\">")
1388N/A .append(line).append("</a>\n");
1388N/A } else {
1388N/A bn.append(line).append('\n');
1388N/A }
1388N/A bs.append(Util.htmlize(file[line-1])).append('\n');
1388N/A }
1388N/A }
1388N/A return --line;
1388N/A}
1388N/A
1388N/Aprivate static final int dumpChunk(int cn, int cl, int line, String[] file,
1388N/A StringBuilder bn, StringBuilder bs, boolean a)
1388N/A{
1388N/A line++;
1388N/A for (int j = cn; j <= cl ; j++, line++) {
1388N/A if (a) {
1388N/A bn.append("<a name=\"").append(line).append("\">")
1388N/A .append(line).append("</a>\n");
1388N/A } else {
1388N/A bn.append(line).append('\n');
1388N/A }
1388N/A bs.append(file[j]).append('\n');
1388N/A }
1388N/A return --line;
1186N/A}
1186N/A%><%@
0N/A
1186N/Ainclude file="mast.jsp"
0N/A
0N/A%><%
1186N/A/* ---------------------- diff.jsp start --------------------- */
1186N/A{
1388N/A cfg = PageConfig.get(request);
1388N/A DiffData dd = cfg.getDiffData();
1281N/A
1388N/A if (dd.errorMsg != null) {
0N/A
1186N/A%>
1186N/A<div class="src">
1281N/A <h3 class="error">Error:</h3>
1388N/A <p><%= dd.errorMsg %></p>
1186N/A</div><%
1186N/A
1388N/A } else if (dd.genre == Genre.IMAGE) {
170N/A
1388N/A String link = request.getContextPath() + Prefix.RAW_P
1388N/A + Util.htmlize(cfg.getPath());
1186N/A%>
1186N/A<div id="difftable">
1388N/A <table class="dtimage">
1281N/A <thead>
1388N/A <tr><th><%= dd.filename %> (revision <%= dd.rev1 %>)</th>
1388N/A <th><%= dd.filename %> (revision <%= dd.rev2 %>)</th>
1281N/A </tr>
1281N/A </thead>
1281N/A <tbody>
1388N/A <tr><td class="dti"><img src="<%= link %>?r=<%= dd.rev1 %>"/></td>
1388N/A <td class="dti"><img src="<%= link %>?r=<%= dd.rev2 %>"/></td>
1281N/A </tr>
1281N/A </tbody>
1281N/A </table>
1186N/A</div><%
170N/A
1388N/A } else if (dd.genre != Genre.PLAIN && dd.genre != Genre.HTML) {
1388N/A String link = request.getContextPath() + Prefix.RAW_P
1388N/A + Util.htmlize(cfg.getPath());
1186N/A%>
1281N/A<div id="src">Diffs for binary files cannot be displayed! Files are <a
1388N/A href="<%= link %>?r=<%= dd.rev1 %>"><%=
1388N/A dd.filename %>(revision <%= dd.rev1 %>)</a> and <a
1388N/A href="<%= link %>?r=<%= dd.rev2 %>"><%=
1388N/A dd.filename %>(revision <%= dd.rev2 %>)</a>.
0N/A</div><%
1388N/A } else if (dd.revision.size() == 0) {
1388N/A %>
1388N/A <%= getAnnotateRevision(dd) %>
1388N/A <b>No differences found!</b><%
1388N/A } else {
1388N/A //-------- Do THE DIFFS ------------
1186N/A%>
1388N/A<%= getAnnotateRevision(dd) %>
1186N/A<div id="diffbar">
1388N/A <div class="dblegend">
1388N/A <span class="m">Deleted</span>
1388N/A <span class="p">Added</span>
1388N/A </div>
1388N/A <div class="dbtabs"><%
1388N/A for (DiffType t : DiffType.values()) {
1388N/A if (dd.type == t) {
1388N/A %> <span class="active dbtab"><%= t.toString() %><%
1388N/A if (t == DiffType.OLD) {
1388N/A %> ( <%= dd.rev1 %> )<%
1388N/A } else if (t == DiffType.NEW) {
1388N/A %> ( <%= dd.rev2 %> )<%
1388N/A }
1388N/A %></span><%
1388N/A } else {
1388N/A %> <span class="dbtab"><a href="<%= dd.reqURI %>?r1=<%= dd.rp1
1388N/A %>&amp;r2=<%= dd.rp2 %>&amp;format=<%= t.getAbbrev()
1388N/A %>&amp;full=<%= dd.full ? '1' : '0' %>"><%= t.toString() %><%
1388N/A if (t == DiffType.OLD) {
1388N/A %> ( <%= dd.rev1 %> )<%
1388N/A } else if (t == DiffType.NEW) {
1388N/A %> ( <%= dd.rev2 %> )<%
1388N/A }
1388N/A %></a></span><%
1388N/A }
1388N/A }
1388N/A %></div>
1388N/A <div class="dbformats"><%
1388N/A if (!dd.full) {
1388N/A %>
1388N/A <span class="dbformat"><a href="<%= dd.reqURI %>?r1=<%= dd.rp1
1388N/A %>&amp;r2=<%= dd.rp2 %>&amp;format=<%= dd.type.getAbbrev()
1388N/A %>&amp;full=1">full</a></span>
1388N/A <span class="active dbformat">compact</span><%
1388N/A } else {
1388N/A %>
1388N/A <span class="active dbformat">full</span>
1388N/A <span class="dbformat"> <a href="<%= dd.reqURI %>?r1=<%= dd.rp1
1388N/A %>&amp;r2=<%= dd.rp2 %>&amp;format=<%= dd.type.getAbbrev()
1388N/A %>&amp;full=0">compact</a></span><%
1388N/A }
1388N/A %></div>
1186N/A</div>
1168N/A
1388N/A<div id="difftable"><%
1388N/A if (dd.type != DiffType.TEXT) {
1388N/A %><table id="<%= "dt" + dd.type %>"><%
1388N/A if (dd.type == DiffType.SIDEBYSIDE) {
1388N/A%>
1388N/A<thead><tr>
1388N/A <th colspan="2"><%= dd.filename %> (<%= dd.rev1 %>)</th>
1388N/A <th colspan="2"><%= dd.filename %> (<%= dd.rev2 %>)</th>
1388N/A</tr></thead><%
1388N/A }
1388N/A%>
1388N/A <tbody><%
1388N/A }
1281N/A
1388N/A StringBuilder bs1 = new StringBuilder(256);
1388N/A StringBuilder bs2 = new StringBuilder(256);
1388N/A StringBuilder bn1 = new StringBuilder(32);
1388N/A StringBuilder bn2 = new StringBuilder(32);
1388N/A int ln1 = 0;
1388N/A int ln2 = 0;
1388N/A String[] file1 = dd.file[0];
1388N/A String[] file2 = dd.file[1];
1388N/A
1388N/A for (int i=0; i < dd.revision.size(); i++) {
1388N/A Delta d = dd.revision.getDelta(i);
1388N/A if (dd.type == DiffType.TEXT) {
1388N/A%><%= Util.htmlize(d.toString()) %><%
1388N/A continue;
1388N/A }
1388N/A Chunk c1 = d.getOriginal();
1388N/A Chunk c2 = d.getRevised();
1388N/A int cn1 = c1.first();
1388N/A int cl1 = c1.last();
1388N/A int cn2 = c2.first();
1388N/A int cl2 = c2.last();
1168N/A
1388N/A int i1 = cn1, i2 = cn2;
1388N/A // changed
1388N/A for (; i1 <= cl1 && i2 <= cl2; i1++, i2++) {
1388N/A bs1.setLength(0);
1388N/A bs2.setLength(0);
1388N/A Util.htmlize(file1[i1], bs1);
1388N/A Util.htmlize(file2[i2], bs2);
1388N/A String[] ss = Util.diffline(bs1, bs2);
1388N/A file1[i1] = ss[0];
1388N/A file2[i2] = ss[1];
1388N/A }
1388N/A // deleted
1388N/A for (; i1 <= cl1; i1++) {
1388N/A bs1.setLength(0);
1388N/A bs1.append(Util.SPAN_D);
1388N/A Util.htmlize(file1[i1], bs1);
1388N/A file1[i1] = bs1.append("</span>").toString();
1388N/A }
1388N/A // added
1388N/A for (; i2 <= cl2; i2++) {
1388N/A bs2.setLength(0);
1388N/A bs2.append(Util.SPAN_A);
1388N/A Util.htmlize(file2[i2], bs2);
1388N/A file2[i2] = bs2.append("</span>").toString();
1388N/A }
1388N/A bn2.setLength(0);
1388N/A bs2.setLength(0);
1388N/A int td = 1;
1388N/A String tClass = " class='dtk'";
1388N/A if (dd.type == DiffType.OLD && cn1 > ln1) {
1388N/A tClass = "";
1388N/A ln1 = dumpFile(ln1, cn1 - ln1, 8, file1, bn2, bs2, dd, true);
1388N/A } else if (dd.type == DiffType.NEW && cn2 > ln2) {
1388N/A tClass = "";
1388N/A ln2 = dumpFile(ln2, cn2 - ln2, 8, file2, bn2, bs2, dd, true);
1388N/A } else if (dd.type == DiffType.UNIFIED && (cn1 > ln1 || cn2 > ln2)) {
1388N/A ln2 = dumpFile(ln2, cn2 - ln2, 8, file2, bn2, bs2, dd, true);
1388N/A ln1 = cn1;
1388N/A } else if (dd.type == DiffType.SIDEBYSIDE && (cn1 > ln1 || cn2 > ln2)) {
1388N/A bn1.setLength(0);
1388N/A bs1.setLength(0);
1388N/A boolean old = dd.full; // force same dump strategy for both
1388N/A dd.full |= cn2 - ln2 < 20;
1388N/A ln1 = dumpFile(ln1, cn1 - ln1, 8, file1, bn1, bs1, dd, false);
1388N/A dd.full = old; // restore
1388N/A ln2 = dumpFile(ln2, cn2 - ln2, 8, file2, bn2, bs2, dd, true);
1388N/A td++;
1388N/A } else {
1388N/A td = 0;
1388N/A }
1388N/A if (td > 0) {
1388N/A%>
1388N/A<tr <%= tClass %>><%
1388N/A if (td > 1) {
1388N/A %>
1388N/A <td class="dtn"><%= bn1 %></td>
1388N/A <td class="dts"><%= bs1 %></td><%
1388N/A }
1388N/A %>
1388N/A <td class="dtn"><%= bn2 %></td>
1388N/A <td class="dts"><%= bs2 %></td>
1388N/A</tr><%
1388N/A }
1388N/A bn2.setLength(0);
1388N/A bs2.setLength(0);
1388N/A td = 1;
1388N/A tClass = " class='dtk'";
1388N/A String tdClass = "dtp";
1388N/A if (dd.type == DiffType.OLD && cn1 <= cl1) {
1388N/A tdClass = "dtm"; tClass = "";
1388N/A ln1 = dumpChunk(cn1, cl1, ln1, file1, bn2, bs2, true);
1388N/A } else if (dd.type == DiffType.NEW && cn2 <= cl2) {
1388N/A tClass = "";
1388N/A ln2 = dumpChunk(cn2, cl2, ln2, file2, bn2, bs2, true);
1388N/A } else if (dd.type == DiffType.UNIFIED) {
1388N/A td = 0;
1388N/A if (cn1 <= cl1) {
1388N/A ln1 = dumpChunk(cn1, cl1, ln1, file1, bn2, bs2, false);
1388N/A%>
1388N/A<tr>
1388N/A <td class="dtm"><%= bn2 %></td>
1388N/A <td class="dts"><%= bs2 %></td>
1388N/A</tr><%
1388N/A }
1388N/A if (cn2 <= cl2) {
1388N/A bn2.setLength(0);
1388N/A bs2.setLength(0);
1388N/A ln2 = dumpChunk(cn2, cl2, ln2, file2, bn2, bs2, true);
1388N/A td = 1;
1388N/A }
1388N/A } else if (dd.type == DiffType.SIDEBYSIDE
1388N/A && (cn1 <= cl1 || cn2 <= cl2))
1388N/A {
1388N/A bn1.setLength(0);
1388N/A bs1.setLength(0);
1388N/A ln1 = dumpChunk(cn1, cl1, ln1, file1, bn1, bs1, false);
1388N/A ln2 = dumpChunk(cn2, cl2, ln2, file2, bn2, bs2, true);
1388N/A td++;
1388N/A } else {
1388N/A td = 0;
1388N/A }
1388N/A if (td > 0) {
1388N/A%>
1388N/A<tr <%= tClass %>><%
1388N/A if (td > 1) {
1388N/A %>
1388N/A <td class="dtm"><%= bn1 %></td>
1388N/A <td class="dts"><%= bs1 %></td><%
1388N/A }
1388N/A %>
1388N/A <td class="<%= tdClass %>"><%= bn2 %></td>
1388N/A <td class="dts"><%= bs2 %></td>
1388N/A</tr><%
1388N/A }
1388N/A } // for
1388N/A // deltas done, dump the remaining
1388N/A if (file1.length >= ln1) {
1388N/A bn2.setLength(0);
1388N/A bs2.setLength(0);
1388N/A int td = 1;
1388N/A if (dd.type == DiffType.OLD && file1.length > ln1) {
1388N/A ln1 = dumpFile(ln1, file1.length - ln1, 0, file1, bn2, bs2, dd, true);
1388N/A } else if (dd.type == DiffType.NEW && file2.length > ln2) {
1388N/A ln2 = dumpFile(ln2, file2.length - ln2, 0, file2, bn2, bs2, dd, true);
1388N/A } else if (dd.type == DiffType.UNIFIED && file2.length > ln2) {
1388N/A ln2 = dumpFile(ln2, file2.length - ln2, 0, file2, bn2, bs2, dd, true);
1388N/A } else if (dd.type == DiffType.SIDEBYSIDE
1388N/A && (file1.length > ln1 || file2.length > ln2))
1388N/A {
1388N/A bn1.setLength(0);
1388N/A bs1.setLength(0);
1388N/A boolean old = dd.full; // force same dump strategy for both
1388N/A dd.full |= file1.length - ln1 < 20;
1388N/A ln1 = dumpFile(ln1, file1.length - ln1, 0, file1, bn1, bs1, dd, false);
1388N/A dd.full = old; // restore
1388N/A ln2 = dumpFile(ln2, file2.length - ln2, 0, file2, bn2, bs2, dd, true);
1388N/A td++;
1388N/A } else {
1388N/A td = 0;
1388N/A }
1388N/A if (td > 0) {
1388N/A%>
1388N/A<tr><%
1388N/A if (td > 1) {
1388N/A %>
1388N/A <td class="dtn"><%= bn1 %></td>
1388N/A <td class="dts"><%= bs1 %></td><%
1388N/A }
1388N/A %>
1388N/A <td class="dtn"><%= bn2 %></td>
1388N/A <td class="dts"><%= bs2 %></td>
1388N/A</tr><%
1388N/A }
1388N/A } // EOFs
1388N/A if (dd.type != DiffType.TEXT ) {
1388N/A %>
1388N/A </tbody>
1388N/A </table><%
1388N/A }
0N/A
1186N/A//----DIFFS Done--------
1388N/A%></div><%
1388N/A }
1186N/A}
1186N/A/* ---------------------- diff.jsp end --------------------- */
1186N/A%><%@
0N/A
1186N/Ainclude file="foot.jspf"
0N/A
1186N/A%>