1 <%-- 2 CDDL HEADER START 3 4 The contents of this file are subject to the terms of the 5 Common Development and Distribution License (the "License"). 6 You may not use this file except in compliance with the License. 7 8 See LICENSE.txt included in this distribution for the specific 9 language governing permissions and limitations under the License. 10 11 When distributing Covered Code, include this CDDL HEADER in each 12 file and include the License file at LICENSE.txt. 13 If applicable, add the following below this CDDL HEADER, with the 14 fields enclosed by brackets "[]" replaced with your own identifying 15 information: Portions Copyright [yyyy] [name of copyright owner] 16 17 CDDL HEADER END 18 19 Copyright 2005 Sun Microsystems, Inc. All rights reserved. 20 Use is subject to license terms. 21 22 ident "@(#)diff.jsp 1.2 05/12/01 SMI" 23 24 --%><%@ page import = "javax.servlet.*, 25 java.lang.*, 26 javax.servlet.http.*, 27 java.util.*, 28 java.io.*, 29 java.text.*, 30 java.net.URLDecoder, 31 org.opensolaris.opengrok.analysis.*, 32 org.opensolaris.opengrok.analysis.FileAnalyzer.Genre, 33 org.opensolaris.opengrok.web.*, 34 org.opensolaris.opengrok.history.*, 35 org.apache.commons.jrcs.diff.*" 36 %><%@include file="mast.jsp"%><%! 37 38 String readableLine(int n) { 39 if (n < 10) { 40 return " " + n; 41 } else { 42 return String.valueOf(n); 43 } 44 } 45 46 String[] diffline(String line1, String line2) { 47 int i=0, j=1; 48 int l1 = line1.length(); 49 int l2 = line2.length(); 50 String[] ret = new String[2]; 51 while (i < l1 && i < l2 && (line1.charAt(i) == line2.charAt(i))) 52 i++; 53 54 while (j < l1 && j < l2 && (line1.charAt(l1 - j) == line2.charAt(l2 - j))) 55 j++; 56 57 StringBuilder sb = new StringBuilder(line1); 58 if(i <= l1 - j) { 59 sb.insert(i, "<span class=\"d\">"); 60 sb.insert(sb.length()-j+1, "</span>"); 61 ret[0] = sb.toString(); 62 } else { 63 ret[0] = line1; 64 } 65 66 if(i <= l2 - j) { 67 sb = new StringBuilder(line2); 68 sb.insert(i, "<span class=\"a\">"); 69 sb.insert(sb.length()-j+1, "</span>"); 70 ret[1] = sb.toString(); 71 } else { 72 ret[1] = line2; 73 } 74 return ret; 75 } 76 77 %><% 78 79 if (valid) { 80 final String rp1 = request.getParameter("r1"); 81 final String rp2 = request.getParameter("r2"); 82 String srcRoot = environment.getSourceRootFile().getAbsolutePath(); 83 84 String r1 = null; 85 String r2 = null; 86 File rpath1 = null; 87 File rpath2 = null; 88 String[] tmp; 89 try { 90 tmp = rp1.split("@"); 91 if (tmp != null && tmp.length == 2) { 92 rpath1 = new File(srcRoot+URLDecoder.decode(tmp[0], "ISO-8859-1")); 93 r1 = URLDecoder.decode(tmp[1], "ISO-8859-1"); 94 } 95 } catch (UnsupportedEncodingException e) { 96 } 97 98 try { 99 tmp = rp2.split("@"); 100 if (tmp != null && tmp.length == 2) { 101 if (tmp != null && tmp.length == 2) { 102 rpath2 = new File(srcRoot+URLDecoder.decode(tmp[0], "ISO-8859-1")); 103 r2 = URLDecoder.decode(tmp[1], "ISO-8859-1"); 104 } 105 } 106 } catch (UnsupportedEncodingException e) { 107 } 108 109 if (r1 == null || r2 == null || r1.equals("") || r2.equals("") || r1.equals(r2)) { 110 %><div class="src"><h3 class="error">Error:</h3> 111 Please pick two revisions to compare the changed from the <a href="<%=context%>/history<%=path%>">history</a> 112 </div><% 113 // Error message ask to choose two versions from History log page with link to it 114 } else { 115 Genre g = AnalyzerGuru.getGenre(basename); 116 if (g == Genre.PLAIN || g == null || g == Genre.DATA || g == Genre.HTML) { 117 InputStream in1 = null; 118 InputStream in2 = null; 119 try{ 120 in1 = HistoryGuru.getInstance().getRevision(rpath1.getParent(), rpath1.getName(), r1); 121 in2 = HistoryGuru.getInstance().getRevision(rpath2.getParent(), rpath2.getName(), r2); 122 } catch (Exception e) { 123 %> <h3 class="error">Error opening revisions!</h3> <% 124 } 125 try { 126 if (in1 != null && in2 != null) { 127 g = AnalyzerGuru.getGenre(basename); 128 if (g == null) { 129 g = AnalyzerGuru.getGenre(in1); 130 } 131 if (g == Genre.IMAGE) { 132 %> <div id="difftable"> 133 <table rules="cols" cellpadding="5"><tr><th><%=basename%> (revision <%=r1%>)</th><th><%=basename%> (revision <%=r2%>)</th></tr> 134 <tr><td><img src="<%=context%>/raw<%=path%>?r=<%=r1%>"/></td><td><img src="<%=context%>/raw<%=path%>?r=<%=r2%>"/></td></tr></table></div><% 135 } else if (g == Genre.PLAIN || g == Genre.HTML) { 136 //--------Do THE DIFFS------------ 137 ArrayList l1 = new ArrayList(); 138 String line; 139 BufferedReader reader1 = new BufferedReader(new InputStreamReader(in1)); 140 BufferedReader reader2 = new BufferedReader(new InputStreamReader(in2)); 141 142 while ((line = reader1.readLine()) != null) { 143 l1.add(line); 144 } 145 146 ArrayList l2 = new ArrayList(); 147 while ((line = reader2.readLine()) != null) { 148 l2.add(line); 149 } 150 Object[] file1 = l1.toArray(); 151 Object[] file2 = l2.toArray(); 152 153 Revision rev = Diff.diff(file1, file2); 154 155 if(rev.size() == 0) { 156 %><b>No differences found!</b><% 157 } else { 158 159 int ln1 = 0; 160 int ln2 = 0; 161 162 String format = request.getParameter("format"); 163 if(format == null || (!format.equals("o") && !format.equals("n") && !format.equals("u") && !format.equals("t"))) 164 format = "s"; 165 String pfull = request.getParameter("full"); 166 boolean full = pfull != null && pfull.equals("1"); 167 pfull = full ? "1" : "0"; 168 169 170 %><div id="difftable"><div id="diffbar"><span class="tabsel"> <span class="d"> Deleted </span> <span class="a"> Added </span> </span> | <% 171 172 if(format.equals("s")) { 173 %><span class="tabsel"><b>sdiff</b></span> <% 174 } else { 175 %><span class="tab"><a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=s&full=<%=pfull%>">sdiff</a></span> <% 176 } 177 178 if(format.equals("u")) { 179 %><span class="tabsel"><b>udiff</b></span> <% 180 } else { 181 %><span class="tab"><a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=u&full=<%=pfull%>">udiff</a></span> <% 182 } 183 184 if(format.equals("t")) { 185 %><span class="tabsel"><b>text</b></span> <% 186 } else { 187 %><span class="tab"><a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=t&full=<%=pfull%>">text</a></span> <% 188 } 189 190 if(format.equals("o")) { 191 %><span class="tabsel"><b>old (<%=r1%>)</b></span> <% 192 } else { 193 %><span class="tab"><a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=o&full=<%=pfull%>">old (<%=r1%>)</a></span> <% 194 } 195 196 if(format.equals("n")) { 197 %><span class="tabsel"><b>new (<%=r2%>)</b></span> | <% 198 } else { 199 %><span class="tab"><a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=n&full=<%=pfull%>">new (<%=r2%>)</a></span> | <% 200 } 201 202 if(!full) { 203 %><span class="tab"><a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=<%=format%>&full=1"> full </a></span> <span class="tabsel"><b>compact</b></span><% 204 } else { 205 %><span class="tabsel"><b> full </b> </span> <span class="tab"> <a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=<%=format%>&full=0">compact</a></span><% 206 } 207 208 if(format.equals("s") || format.equals("u")) { 209 %></div><pre wrap><table cellpadding="2" cellspacing="1" border="0" rules="cols"><% 210 if(format.equals("s")) { 211 %><tr><th><%=basename%> (<%=r1%>)</th><th><%=basename%> (<%=r2%>)</th></tr><% 212 } 213 } else { 214 %></div><pre wrap><% 215 } 216 217 for (int i=0; i < rev.size(); i++) { 218 Delta d = rev.getDelta(i); 219 if(format.equals("t")) { 220 %><%=Util.htmlize(d.toString())%><% 221 } else { 222 Chunk c1 = d.getOriginal(); 223 Chunk c2 = d.getRevised(); 224 int cn1 = c1.first(); 225 int cl1 = c1.last(); 226 int cn2 = c2.first(); 227 int cl2 = c2.last(); 228 229 int i1 = cn1, i2 = cn2; 230 for (; i1 <= cl1 && i2 <= cl2; i1++, i2++) { 231 String[] ss = diffline(Util.htmlize((String)file1[i1]), Util.htmlize((String)file2[i2])); 232 file1[i1] = ss[0]; 233 file2[i2] = ss[1]; 234 } 235 if(i1 <= cl1) { 236 for(int h=i1; h<= cl1; h++) { 237 file1[h] = Util.htmlize((String)file1[h]); 238 } 239 file1[i1] = "<span class=\"d\">" + file1[i1]; 240 file1[cl1] = file1[cl1] + "</span>"; 241 } 242 if(i2 <= cl2) { 243 for(int h=i2; h<= cl2; h++) { 244 file2[h] = Util.htmlize((String)file2[h]); 245 } 246 file2[i2] = "<span class=\"a\">" + file2[i2]; 247 file2[cl2] = file2[cl2] + "</span>"; 248 } 249 250 if (format.equals("u")) { 251 // UDIFF 252 if (cn1 > ln1 || cn2 > ln2) { 253 %><tr class="k"><td><% 254 if (full || (cn2 - ln2 < 20)) { 255 for (int j = ln2; j < cn2; j++) { 256 %><i><%=readableLine(++ln2)%></i><%=Util.htmlize((String)file2[j])%><br/><% 257 } 258 } else { 259 for (int j = ln2; j < ln2+8; j++) { 260 %><i><%=readableLine(j+1)%></i><%=Util.htmlize((String)file2[j])%><br/><% 261 } 262 %><br/>--- <b><%=cn2 - ln2 - 16%> unchanged lines hidden</b> (<a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=<%=format%>&full=1#<%=ln2%>">view full</a>) --- <br/><br/><% 263 ln2 = cn2-8; 264 for (int j = cn2 - 8; j < cn2; j++) { 265 %><i><%=readableLine(++ln2)%></i><%=Util.htmlize((String)file2[j])%><br/><% 266 } 267 } 268 %></td></tr><% 269 ln1 = cn1; 270 } 271 if(cn1 <= cl1) { 272 %><tr><td class="d"><% 273 for(int j = cn1; j <= cl1 ; j++) { 274 %><strike class="d"><%=readableLine(++ln1)%></strike><%=file1[j]%><br/><% 275 } 276 %></td></tr><% 277 } 278 if(cn2 <= cl2) { 279 %><tr class="k"><td><% 280 for(int j = cn2; j < cl2; j++) { 281 %><i class="a"><%=readableLine(++ln2)%></i><%=file2[j]%><br/><% 282 } 283 %><i class="a"><%=readableLine(++ln2)%></i><%=file2[cl2]%><% 284 if(full) { 285 %><a name="<%=ln2%>" /><% 286 } 287 %></td></tr><% 288 } 289 // SDIFF by default 290 } else if(format.equals("s")) { 291 292 if (cn1 > ln1 || cn2 > ln2) { 293 %><tr class="k"><td><% 294 if(full || cn2 - ln2 < 20) { 295 for(int j = ln1; j < cn1; j++) { 296 %><i><%=readableLine(++ln1)%></i><%=Util.htmlize((String)file1[j])%><br/><% 297 } 298 %></td><td><% 299 for(int j = ln2; j < cn2 ; j++) { 300 %><i><%=readableLine(++ln2)%></i><%=Util.htmlize((String)file2[j])%><br/><% 301 } 302 } else { 303 for(int j = ln1; j < ln1+8; j++) { 304 %><i><%=readableLine(j+1)%></i><%=Util.htmlize((String)file1[j])%><br/><% 305 } 306 %><br/>--- <b><%=cn1 - ln1 - 16%> unchanged lines hidden</b> (<a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=<%=format%>&full=1#<%=ln2%>">view full</a>) --- <br/><br/><% 307 ln1 = cn1-8; 308 for (int j = cn1 - 8; j < cn1; j++) { 309 %><i><%=readableLine(++ln1)%></i><%=Util.htmlize((String)file1[j])%><br/><% 310 } 311 %></td><td><% 312 for (int j = ln2; j < ln2+8; j++) { 313 %><i><%=readableLine(j+1)%></i><%=Util.htmlize((String)file2[j])%><br/><% 314 } 315 %><br/>--- <b><%=cn2 - ln2 - 16%> unchanged lines hidden</b> (<a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=<%=format%>&full=1#<%=ln2%>">view full</a>) --- <br/><br/><% 316 ln2 = cn2-8; 317 for (int j = cn2 - 8; j < cn2; j++) { 318 %><i><%=readableLine(++ln2)%></i><%=Util.htmlize((String)file2[j])%><br/><% 319 } 320 } 321 %></td></tr><% 322 } 323 324 %><tr valign="top" class="k"><td><% 325 for(int j = cn1; j <= cl1; j++) { 326 %><i><%=readableLine(++ln1)%></i><%=file1[j]%><br/><% 327 } 328 %></td><td><% 329 for(int j = cn2; j <= cl2; j++) { 330 %><i><%=readableLine(++ln2)%></i><a name="<%=ln2%>" /></a><%=file2[j]%><br/><% 331 } 332 %></td></tr><% 333 334 // OLD ----- 335 } else if ( format.equals("o")) { 336 if (cn1 > ln1) { 337 if(full || cn1 - ln1 < 20) { 338 for(int j = ln1; j < cn1; j++) { 339 %><i><%=readableLine(++ln1)%></i><%=Util.htmlize((String)file1[j])%><br/><% 340 } 341 } else { 342 for(int j = ln1; j < ln1+8; j++) { 343 %><i><%=readableLine(j+1)%></i><%=Util.htmlize((String)file1[j])%><br/><% 344 } 345 %><br/>--- <b><%=cn1 - ln1 - 16%> unchanged lines hidden</b> (<a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=<%=format%>&full=1#<%=ln1%>">view full</a>) --- <br/><br/><% 346 ln1 = cn1-8; 347 for (int j = cn1 - 8; j < cn1; j++) { 348 %><i><%=readableLine(++ln1)%></i><%=Util.htmlize((String)file1[j])%><br/><% 349 } 350 } 351 } 352 for(int j = cn1; j <= cl1 ; j++) { 353 %><i><%=readableLine(++ln1)%></i><%=file1[j]%><br/><% 354 } 355 if(full) { 356 %><a name="<%=ln1%>" ></a><% 357 } 358 359 // NEW ----------- 360 } else if ( format.equals("n")) { 361 362 if (cn2 > ln2) { 363 if(full || cn2 - ln2 < 20) { 364 for(int j = ln2; j < cn2 ; j++) { 365 %><i><%=readableLine(++ln2)%></i><%=Util.htmlize((String)file2[j])%><br/><% 366 } 367 } else { 368 for (int j = ln2; j < ln2+8; j++) { 369 %><i><%=readableLine(j+1)%></i><%=Util.htmlize((String)file2[j])%><br/><% 370 } 371 %><br/>--- <b><%=cn2 - ln2 - 16%> unchanged lines hidden</b> (<a href="<%=reqURI%>?r1=<%=rp1%>&r2=<%=rp2%>&format=<%=format%>&full=1#<%=ln2%>">view full</a>) --- <br/><br/><% 372 ln2 = cn2-8; 373 for (int j = cn2 - 8; j < cn2; j++) { 374 %><i><%=readableLine(++ln2)%></i><%=Util.htmlize((String)file2[j])%><br/><% 375 } 376 } 377 } 378 for(int j = cn2; j <= cl2 ; j++) { 379 %><i><%=readableLine(++ln2)%></i><%=file2[j]%><br/><% 380 } 381 if(full) { 382 %><a name="<%=ln2%>"></a><% 383 } 384 385 } 386 } 387 } 388 389 390 if (file1.length >= ln1) { 391 // dump the remaining 392 if (format.equals("s")) { 393 if (full || file1.length - ln1 < 20) { 394 %><tr><td><% 395 for (int j = ln1; j < file1.length ; j++) { 396 %><i><%=(j+1)%></i><%=Util.htmlize((String)file1[j])%><br/><% 397 } 398 %></td><td><% 399 for (int j = ln2; j < file2.length ; j++) { 400 %><i><%=(j+1)%></i><%=Util.htmlize((String)file2[j])%><br/><% 401 } 402 %></td></tr></table><% 403 } else { 404 %><tr><td><% 405 for (int j = ln1; j < ln1 + 8 ; j++) { 406 %><i><%=(j+1)%></i><%=Util.htmlize((String)file1[j])%><br/><% 407 } 408 409 %><br/> --- <b><%=file1.length - ln1 - 8%> unchanged lines hidden</b> --- </td><td><% 410 for (int j = ln2; j < ln2 + 8 ; j++) { 411 %><i><%=(j+1)%></i><%=Util.htmlize((String)file2[j])%><br/><% 412 } 413 %><br/>--- <b><%=file1.length - ln1 - 8%> unchanged lines hidden</b> ---</td></tr></table><% 414 } 415 } else if (format.equals("u")) { 416 if (full || file2.length - ln2 < 20) { 417 %><tr><td><% 418 for (int j = ln2; j < file2.length ; j++) { 419 %><i><%=(j+1)%></i><%=Util.htmlize((String)file2[j])%><br/><% 420 } 421 %></td></tr></table><% 422 } else { 423 %><tr><td><% 424 for (int j = ln2; j < ln2 + 8 ; j++) { 425 %><i><%=(j+1)%></i><%=Util.htmlize((String)file2[j])%><br/><% 426 } 427 %><br/>--- <b><%=file2.length - ln2 - 8%> unchanged lines hidden</b> ---</td></tr></table><% 428 } 429 } else if (format.equals("o")) { 430 if (full || file1.length - ln1 < 20) { 431 for (int j = ln1; j < file1.length ; j++) { 432 %><i><%=(j+1)%></i><%=Util.htmlize((String)file1[j])%><br/><% 433 } 434 } else { 435 for (int j = ln1; j < ln1 + 8 ; j++) { 436 %><i><%=(j+1)%></i><%=Util.htmlize((String)file1[j])%><br/><% 437 } 438 439 %><br/> --- <b><%=file1.length - ln1 - 8%> unchanged lines hidden</b> ---<br/><% 440 } 441 } else if (format.equals("n")) { 442 if (full || file2.length - ln2 < 20) { 443 for (int j = ln2; j < file2.length ; j++) { 444 %><i><%=(j+1)%></i><%=Util.htmlize((String)file2[j])%><br/><% 445 } 446 } else { 447 for (int j = ln2; j < ln2 + 8 ; j++) { 448 %><i><%=(j+1)%></i><%=Util.htmlize((String)file2[j])%><br/><% 449 } 450 %><br/> --- <b><%=file2.length - ln2 - 8%> unchanged lines hidden</b> ---<br/><% 451 } 452 } 453 454 } 455 456 //----DIFFS Done-------- 457 %></pre></div><% 458 } 459 } else { 460 %> <div id="src">Diffs for binary files cannot be displayed! Files are <a href="<%=context%>/raw<%=path%>?r=<%=r1%>"><%=basename%>(revision <%=r1%>)</a> and 461 <a href="<%=context%>/raw<%=path%>?r=<%=r2%>"><%=basename%>(revision <%=r2%>)</a>. 462 </div><% 463 } 464 } 465 } catch (FileNotFoundException e) { 466 %><div class="src"><h3 class="error">Error Opening files! <%=Util.htmlize(e.getMessage())%></h3></div><% 467 } 468 if(in1 != null) 469 in1.close(); 470 if(in2 != null) 471 in2.close(); 472 } else if (g == Genre.IMAGE) { 473 %> <div class="src"> 474 <table rules="cols" cellpadding="5"><tr><th><%=basename%> (revision <%=r1%>)</th><th><%=basename%> (revision <%=r2%>)</th></tr> 475 <tr><td><img src="<%=context%>/raw<%=path%>?r=<%=r1%>"/></td><td><img src="<%=context%>/raw<%=path%>?r=<%=r2%>"/></td></tr></table></div><% 476 477 } else { 478 %> <div class="src">Diffs for binary files cannot be displayed. Files are <a href="<%=context%>/raw<%=path%>?r=<%=r1%>"><%=basename%>(revision <%=r1%>)</a> and 479 <a href="<%=context%>/raw<%=path%>?r=<%=r2%>"><%=basename%>(revision <%=r2%>)</a>. 480 </div><% 481 } 482 } 483 %><%@include file="foot.jspf"%><% 484 } 485 %> 486