1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.util;
24  
25  import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
26  import com.liferay.portal.kernel.util.DiffHtml;
27  import com.liferay.portal.kernel.util.LocaleUtil;
28  import com.liferay.portal.kernel.util.StringPool;
29  
30  import java.io.Reader;
31  
32  import java.util.Locale;
33  
34  import javax.xml.transform.TransformerFactory;
35  import javax.xml.transform.sax.SAXTransformerFactory;
36  import javax.xml.transform.sax.TransformerHandler;
37  import javax.xml.transform.stream.StreamResult;
38  
39  import org.outerj.daisy.diff.HtmlCleaner;
40  import org.outerj.daisy.diff.XslFilter;
41  import org.outerj.daisy.diff.html.HTMLDiffer;
42  import org.outerj.daisy.diff.html.HtmlSaxDiffOutput;
43  import org.outerj.daisy.diff.html.TextNodeComparator;
44  import org.outerj.daisy.diff.html.dom.DomTreeBuilder;
45  
46  import org.xml.sax.ContentHandler;
47  import org.xml.sax.InputSource;
48  import org.xml.sax.helpers.AttributesImpl;
49  
50  /**
51   * <a href="DiffHtmlImpl.java.html"><b><i>View Source</i></b></a>
52   *
53   * <p>
54   * This class can compare two different versions of HTML code. It detects
55   * changes to an entire HTML page such as removal or addition of characters or
56   * images.
57   * </p>
58   *
59   * @author Julio Camarero
60   */
61  public class DiffHtmlImpl implements DiffHtml {
62  
63      /**
64       * This is a diff method with default values.
65       *
66       * @return a string containing the HTML code of the source text showing the
67       *         differences with the target text
68       */
69      public String diff(Reader source, Reader target) throws Exception {
70          InputSource oldSource = new InputSource(source);
71          InputSource newSource = new InputSource(target);
72  
73          UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter(true);
74  
75          SAXTransformerFactory saxTransformerFactory =
76              (SAXTransformerFactory)TransformerFactory.newInstance();
77  
78          TransformerHandler tranformHandler =
79              saxTransformerFactory.newTransformerHandler();
80  
81          tranformHandler.setResult(new StreamResult(unsyncStringWriter));
82  
83          XslFilter xslFilter = new XslFilter();
84  
85          ContentHandler contentHandler = xslFilter.xsl(
86              tranformHandler,
87              "com/liferay/portal/util/dependencies/diff_html.xsl");
88  
89          HtmlCleaner htmlCleaner = new HtmlCleaner();
90  
91          DomTreeBuilder oldDomTreeBuilder = new DomTreeBuilder();
92  
93          htmlCleaner.cleanAndParse(oldSource, oldDomTreeBuilder);
94  
95          Locale locale = LocaleUtil.getDefault();
96  
97          TextNodeComparator leftTextNodeComparator = new TextNodeComparator(
98              oldDomTreeBuilder, locale);
99  
100         DomTreeBuilder newDomTreeBuilder = new DomTreeBuilder();
101 
102         htmlCleaner.cleanAndParse(newSource, newDomTreeBuilder);
103 
104         TextNodeComparator rightTextNodeComparator = new TextNodeComparator(
105             newDomTreeBuilder, locale);
106 
107         contentHandler.startDocument();
108         contentHandler.startElement(
109             StringPool.BLANK, _DIFF_REPORT, _DIFF_REPORT, new AttributesImpl());
110         contentHandler.startElement(
111             StringPool.BLANK, _DIFF, _DIFF, new AttributesImpl());
112 
113         HtmlSaxDiffOutput htmlSaxDiffOutput = new HtmlSaxDiffOutput(
114             contentHandler, _DIFF);
115 
116         HTMLDiffer htmlDiffer = new HTMLDiffer(htmlSaxDiffOutput);
117 
118         htmlDiffer.diff(leftTextNodeComparator, rightTextNodeComparator);
119 
120         contentHandler.endElement(StringPool.BLANK, _DIFF, _DIFF);
121         contentHandler.endElement(StringPool.BLANK, _DIFF_REPORT, _DIFF_REPORT);
122         contentHandler.endDocument();
123 
124         unsyncStringWriter.flush();
125 
126         return unsyncStringWriter.toString();
127     }
128 
129     private static final String _DIFF = "diff";
130 
131     private static final String _DIFF_REPORT = "diffreport";
132 
133 }