KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > blandware > atleap > webapp > util > core > MergeUtil


1 /*
2  * Copyright 2004 Blandware (http://www.blandware.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  */

16 package com.blandware.atleap.webapp.util.core;
17
18 import jlibdiff.Diff;
19 import jlibdiff.Hunk;
20 import jlibdiff.HunkAdd;
21 import jlibdiff.HunkChange;
22 import jlibdiff.HunkDel;
23 import jlibdiff.HunkVisitor;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 import java.io.BufferedReader JavaDoc;
28 import java.io.StringReader JavaDoc;
29 import java.util.ArrayList JavaDoc;
30
31 /**
32  * <p>Merge two strings of HTML or plain text</p>
33  * <p/>
34  * <p><a HREF="MergeUtil.java.htm"><i>View Source</i></a></p>
35  *
36  * @author Andrey Grebnev <a HREF="mailto:andrey.grebnev@blandware.com">&lt;andrey.grebnev@blandware.com&gt;</a>
37  * @version $Revision: 1.5 $ $Date: 2006/03/16 11:09:43 $
38  */

39 public class MergeUtil {
40
41     public static final int OLD_HTML = 0;
42     public static final int NEW_HTML = 1;
43
44     /**
45      * <p>Merges the HTML</p>
46      * <p>The changes will be emphasized using div with following styles: addHtml, oldHtml, newHtml, delHtml</p>
47      * <p>If some error is occured the text will be empty</p>
48      * <p>If htmls are identical, the old text will be as result</p>
49      *
50      * @param oldString Old HTML string
51      * @param newString New HTML string
52      * @return merged HTML
53      */

54     public static String JavaDoc mergeHtml(String JavaDoc oldString, String JavaDoc newString) {
55         Log log = LogFactory.getLog(MergeUtil.class);
56
57         final ArrayList JavaDoc hunks = new ArrayList JavaDoc();
58         BufferedReader JavaDoc oldReader = new BufferedReader JavaDoc(new StringReader JavaDoc(oldString));
59         BufferedReader JavaDoc newReader = new BufferedReader JavaDoc(new StringReader JavaDoc(newString));
60         StringBuffer JavaDoc mergedHtml = new StringBuffer JavaDoc();
61
62         try {
63             Diff diff = new Diff();
64             diff.diffBuffer(oldReader, newReader);
65             diff.accept(new HunkVisitor() {
66                 public void visitHunkAdd(HunkAdd hunkAdd) {
67                     hunks.add(hunkAdd);
68                 }
69
70                 public void visitHunkChange(HunkChange hunkChange) {
71                     hunks.add(hunkChange);
72                 }
73
74                 public void visitHunkDel(HunkDel hunkDel) {
75                     hunks.add(hunkDel);
76                 }
77             });
78
79             int position = 0;
80             if ( hunks.size() != 0 ) {
81                 for ( int i = 0; i < hunks.size(); i++ ) {
82                     Hunk hunk = (Hunk) hunks.get(i);
83
84                     if ( hunk instanceof HunkAdd ) {
85                         mergedHtml.append(oldString.substring(position, getOffsetSOL(hunk.lowLine(OLD_HTML), oldString)))
86                                 .append("<div class=\"addHtml\">")
87                                 .append(newString.substring(getOffsetSOL(hunk.lowLine(NEW_HTML) - 1, newString), getOffsetEOL(hunk.highLine(NEW_HTML) - 1, newString)))
88                                 .append("</div>");
89                         position = getOffsetSOL(hunk.highLine(OLD_HTML), oldString);
90                     } else if ( hunk instanceof HunkChange ) {
91                         mergedHtml.append(oldString.substring(position, getOffsetSOL(hunk.lowLine(OLD_HTML) - 1, oldString)))
92                                 .append("<div class=\"oldHtml\">")
93                                 .append(oldString.substring(getOffsetSOL(hunk.lowLine(OLD_HTML) - 1, oldString), getOffsetEOL(hunk.highLine(OLD_HTML) - 1, oldString)))
94                                 .append("</div>\n")
95                                 .append("<div class=\"newHtml\">")
96                                 .append(newString.substring(getOffsetSOL(hunk.lowLine(NEW_HTML) - 1, newString), getOffsetEOL(hunk.highLine(NEW_HTML) - 1, newString)))
97                                 .append("</div>");
98                         position = getOffsetSOL(hunk.highLine(OLD_HTML), oldString);
99                     } else /* HunkDel */ {
100                         mergedHtml.append(oldString.substring(position, getOffsetSOL(hunk.lowLine(OLD_HTML) - 1, oldString)))
101                                 .append("<div class=\"delHtml\">")
102                                 .append(oldString.substring(getOffsetSOL(hunk.lowLine(OLD_HTML) - 1, oldString), getOffsetEOL(hunk.highLine(OLD_HTML) - 1, oldString)))
103                                 .append("</div>");
104                         position = getOffsetSOL(hunk.highLine(OLD_HTML), oldString);
105                     }
106                 }
107                 mergedHtml.append(oldString.substring(position));
108             } else {
109                 //if identical
110
mergedHtml.append(oldString);
111             }
112
113         } catch ( Exception JavaDoc ex ) {
114             if ( log.isErrorEnabled() ) {
115                 log.error("Cannot merge html cause" + ex.getLocalizedMessage(), ex);
116             }
117         } finally {
118             try {
119                 oldReader.close();
120                 newReader.close();
121             } catch ( Exception JavaDoc ex2 ) {
122                 //do nothing
123
}
124         }
125
126         return mergedHtml.toString();
127     }
128
129     /**
130      * <p>Merge the plain text specified in constructor.</p>
131      * <p>The changes will be emphasized using sequences of special symbols</p>
132      * <p>If some error is occured the text will be empty</p>
133      * <p>If texts are identical, the old text will be as result</p>
134      *
135      * @param oldString old text
136      * @param newString new text
137      * @return merged text
138      */

139     public static String JavaDoc mergeText(String JavaDoc oldString, String JavaDoc newString) {
140         Log log = LogFactory.getLog(MergeUtil.class);
141
142         final ArrayList JavaDoc hunks = new ArrayList JavaDoc();
143         BufferedReader JavaDoc oldReader = new BufferedReader JavaDoc(new StringReader JavaDoc(oldString));
144         BufferedReader JavaDoc newReader = new BufferedReader JavaDoc(new StringReader JavaDoc(newString));
145         StringBuffer JavaDoc mergedText = new StringBuffer JavaDoc();
146
147         try {
148             Diff diff = new Diff();
149             diff.diffBuffer(oldReader, newReader);
150             diff.accept(new HunkVisitor() {
151                 public void visitHunkAdd(HunkAdd hunkAdd) {
152                     hunks.add(hunkAdd);
153                 }
154
155                 public void visitHunkChange(HunkChange hunkChange) {
156                     hunks.add(hunkChange);
157                 }
158
159                 public void visitHunkDel(HunkDel hunkDel) {
160                     hunks.add(hunkDel);
161                 }
162             });
163
164             int position = 0;
165             if ( hunks.size() != 0 ) {
166                 for ( int i = 0; i < hunks.size(); i++ ) {
167                     Hunk hunk = (Hunk) hunks.get(i);
168
169                     if ( hunk instanceof HunkAdd ) {
170                         mergedText.append(oldString.substring(position, getOffsetSOL(hunk.lowLine(OLD_HTML), oldString)))
171                                 .append(">>>>>>>>>>>>>>>>>>>>")
172                                 .append(newString.substring(getOffsetSOL(hunk.lowLine(NEW_HTML) - 1, newString), getOffsetEOL(hunk.highLine(NEW_HTML) - 1, newString)))
173                                 .append(">>>>>>>>>>>>>>>>>>>>");
174                         position = getOffsetSOL(hunk.highLine(OLD_HTML), oldString);
175                     } else if ( hunk instanceof HunkChange ) {
176                         mergedText.append(oldString.substring(position, getOffsetSOL(hunk.lowLine(OLD_HTML) - 1, oldString)))
177                                 .append("<<<<<<<<<<<<<<<<<<<<")
178                                 .append(oldString.substring(getOffsetSOL(hunk.lowLine(OLD_HTML) - 1, oldString), getOffsetEOL(hunk.highLine(OLD_HTML) - 1, oldString)))
179                                 .append("\n<<<<<<<<<<<<<<<<<<<<\n")
180                                 .append(">>>>>>>>>>>>>>>>>>>>")
181                                 .append(newString.substring(getOffsetSOL(hunk.lowLine(NEW_HTML) - 1, newString), getOffsetEOL(hunk.highLine(NEW_HTML) - 1, newString)))
182                                 .append("\n>>>>>>>>>>>>>>>>>>>>");
183                         position = getOffsetSOL(hunk.highLine(OLD_HTML), oldString);
184                     } else /* HunkDel */ {
185                         mergedText.append(oldString.substring(position, getOffsetSOL(hunk.lowLine(OLD_HTML) - 1, oldString)))
186                                 .append("--------------------")
187                                 .append(oldString.substring(getOffsetSOL(hunk.lowLine(OLD_HTML) - 1, oldString), getOffsetEOL(hunk.highLine(OLD_HTML) - 1, oldString)))
188                                 .append("--------------------");
189                         position = getOffsetSOL(hunk.highLine(OLD_HTML), oldString);
190                     }
191                 }
192                 mergedText.append(oldString.substring(position));
193             } else {
194                 //if identical
195
mergedText.append(oldString);
196             }
197
198         } catch ( Exception JavaDoc ex ) {
199             if ( log.isErrorEnabled() ) {
200                 log.error("Cannot merge text cause" + ex.getLocalizedMessage(), ex);
201             }
202         } finally {
203             try {
204                 oldReader.close();
205                 newReader.close();
206             } catch ( Exception JavaDoc ex2 ) {
207                 //do nothing
208
}
209         }
210
211         return mergedText.toString();
212     }
213
214
215     /**
216      * Returns offset of start of line
217      *
218      * @param linenumber
219      * @param buffer
220      * @return offset of the start of the line or 0 is the first is the first line
221      */

222     protected static int getOffsetSOL(int linenumber, String JavaDoc buffer) {
223         if ( linenumber == 0 ) {
224             return 0;
225         } else {
226             int counter = 0;
227             int offset = -1;
228             int tmp = -1;
229             while ( counter < linenumber ) {
230                 offset++;
231                 counter++;
232                 tmp = buffer.indexOf('\n', offset);
233                 if ( tmp == -1 ) {
234                     return buffer.length();
235                 }
236                 offset = tmp;
237             }
238             return offset;
239         }
240     }
241
242     /**
243      * Return offset of the end of the line
244      *
245      * @param linenumber
246      * @param buffer
247      * @return offset
248      */

249     protected static int getOffsetEOL(int linenumber, String JavaDoc buffer) {
250         int offsetSOL = getOffsetSOL(linenumber, buffer);
251         int offsetEOL = buffer.indexOf('\n', offsetSOL + 1);
252         if ( offsetEOL == -1 ) {
253             return buffer.length();
254         } else {
255             return offsetEOL;
256         }
257     }
258
259 /*
260
261     public static void main(String[] args) {
262         try {
263             String oldHtml = readFile("C:\\TOOLS\\java\\jlibdiff\\1.txt");
264             String newHtml = readFile("C:\\TOOLS\\java\\jlibdiff\\2.txt");
265             String mergedHtml = MergeUtil.mergeText(oldHtml, newHtml);
266             System.out.println(mergedHtml);
267         } catch(Exception ex) {
268             ex.printStackTrace();
269         }
270     }
271
272     protected static String readFile(String fileName) throws Exception {
273         FileInputStream inputStream = new FileInputStream(fileName);
274         int fileSize = inputStream.available();
275         byte[] fileContent = new byte[fileSize];
276         inputStream.read(fileContent, 0, fileSize);
277         inputStream.close();
278         return new String(fileContent, "UTF-8");
279     }
280 */

281
282 }
283
Popular Tags