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