lemval
2012-01-31 1c30dad2115fc513791d8a5b292ad0f7d7b85749
commit | author | age
f13c4c 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
3df349 16 package com.gitblit.utils;
JM 17
18 import java.io.ByteArrayOutputStream;
19 import java.io.IOException;
20 import java.io.OutputStream;
21
22 import org.eclipse.jgit.diff.RawText;
23
d9f687 24 /**
JM 25  * Generates an html snippet of a diff in Gitblit's style.
26  * 
27  * @author James Moger
28  * 
29  */
3df349 30 public class GitBlitDiffFormatter extends GitWebDiffFormatter {
JM 31
32     private final OutputStream os;
33
2a7306 34     private int left, right;
3df349 35
JM 36     public GitBlitDiffFormatter(OutputStream os) {
37         super(os);
38         this.os = os;
39     }
40
41     /**
42      * Output a hunk header
43      * 
44      * @param aStartLine
45      *            within first source
46      * @param aEndLine
47      *            within first source
48      * @param bStartLine
49      *            within second source
50      * @param bEndLine
51      *            within second source
52      * @throws IOException
53      */
54     @Override
2a7306 55     protected void writeHunkHeader(int aStartLine, int aEndLine, int bStartLine, int bEndLine)
JM 56             throws IOException {
3df349 57         os.write("<tr><th>..</th><th>..</th><td class='hunk_header'>".getBytes());
JM 58         os.write('@');
59         os.write('@');
60         writeRange('-', aStartLine + 1, aEndLine - aStartLine);
61         writeRange('+', bStartLine + 1, bEndLine - bStartLine);
62         os.write(' ');
63         os.write('@');
64         os.write('@');
65         os.write("</td></tr>\n".getBytes());
66         left = aStartLine + 1;
67         right = bStartLine + 1;
68     }
69
70     @Override
2a7306 71     protected void writeLine(final char prefix, final RawText text, final int cur)
JM 72             throws IOException {
3df349 73         os.write("<tr>".getBytes());
JM 74         switch (prefix) {
75         case '+':
76             os.write(("<th></th><th>" + (right++) + "</th>").getBytes());
77             os.write("<td><div class=\"diff add2\">".getBytes());
78             break;
79         case '-':
80             os.write(("<th>" + (left++) + "</th><th></th>").getBytes());
81             os.write("<td><div class=\"diff remove2\">".getBytes());
82             break;
83         default:
84             os.write(("<th>" + (left++) + "</th><th>" + (right++) + "</th>").getBytes());
85             os.write("<td>".getBytes());
86             break;
87         }
88         os.write(prefix);
89         ByteArrayOutputStream bos = new ByteArrayOutputStream();
90         text.writeLine(bos, cur);
91         String line = bos.toString();
92         line = StringUtils.escapeForHtml(line, false);
93         os.write(line.getBytes());
94         switch (prefix) {
95         case '+':
96         case '-':
97             os.write("</div>".getBytes());
98             break;
99         default:
100             os.write("</td>".getBytes());
101         }
102         os.write("</tr>\n".getBytes());
103     }
104
105     /**
106      * Workaround function for complex private methods in DiffFormatter. This
107      * sets the html for the diff headers.
108      * 
109      * @return
110      */
111     @Override
112     public String getHtml() {
113         String html = os.toString();
114         String[] lines = html.split("\n");
2a7306 115         StringBuilder sb = new StringBuilder();
3df349 116         boolean inFile = false;
JM 117         String oldnull = "a/dev/null";
118         for (String line : lines) {
119             if (line.startsWith("index")) {
120                 // skip index lines
121             } else if (line.startsWith("new file")) {
122                 // skip new file lines
a645ba 123             } else if (line.startsWith("\\ No newline")) {
JM 124                 // skip no new line
125             } else if (line.startsWith("---") || line.startsWith("+++")) {
126                 // skip --- +++ lines
3df349 127             } else if (line.startsWith("diff")) {
JM 128                 if (line.indexOf(oldnull) > -1) {
129                     // a is null, use b
130                     line = line.substring(("diff --git " + oldnull).length()).trim();
2a7306 131                     // trim b/
JM 132                     line = line.substring(2);
3df349 133                 } else {
JM 134                     // use a
135                     line = line.substring("diff --git a/".length()).trim();
136                     line = line.substring(0, line.indexOf(" b/")).trim();
137                 }
138                 if (inFile) {
139                     sb.append("</tbody></table></div>\n");
140                     inFile = false;
141                 }
142                 sb.append("<div class='header'>").append(line).append("</div>");
2a7306 143                 sb.append("<div class=\"diff\">");
3df349 144                 sb.append("<table><tbody>");
JM 145                 inFile = true;
146             } else {
b5b402 147                 sb.append(line);
3df349 148             }
JM 149         }
150         sb.append("</table></div>");
151         return sb.toString();
152     }
153 }