View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
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  
17  package org.apache.commons.jelly.tags.xmlunit;
18  
19  import java.io.IOException;
20  import javax.xml.parsers.ParserConfigurationException;
21  
22  import org.apache.commons.jelly.JellyTagException;
23  import org.apache.commons.jelly.XMLOutput;
24  import org.custommonkey.xmlunit.Diff;
25  import org.custommonkey.xmlunit.XMLUnit;
26  import org.dom4j.Document;
27  import org.dom4j.io.SAXReader;
28  import org.xml.sax.SAXException;
29  
30  /***
31   * Compares two XML documents using XMLUnit (http://xmlunit.sourceforge.net/).
32   * If they are different an exception will be thrown.
33   */
34  public class AssertDocumentsEqualTag extends XMLUnitTagSupport {
35  
36      private Object actual;
37      private Document actualDocument;
38  
39      private Object expected;
40      private Document expectedDocument;
41  
42      /***
43       * Controls whether whitespace differences are reported as differences.
44       *
45       * Defaults to <code>false</code>, so if <code>trim</code> is set to
46       * <code>false</code> whitespace differences are detected.
47       */
48      private boolean ignoreWhitespace = false;
49  
50      public void doTag(XMLOutput output) throws JellyTagException {
51          invokeBody(output);
52  
53          if (actual != null) {
54              if (actualDocument != null) {
55                  fail("Cannot specify both actual attribute and element");
56              }
57              actualDocument = parse(actual);
58          }
59  
60          if (expected != null) {
61              if (expectedDocument != null) {
62                  fail("Cannot specify both expected attribute and element");
63              }
64              expectedDocument = parse(expected);
65          }
66  
67          if ((expectedDocument == null
68              || expectedDocument.getRootElement() == null)
69              && (actualDocument == null
70                  || actualDocument.getRootElement() == null)) {
71              return;
72          }
73  
74          if (actualDocument != null) {
75              XMLUnit.setIgnoreWhitespace(ignoreWhitespace);
76  
77              Diff delta = null;
78              try {
79                  delta = XMLUnit.compare(
80                      expectedDocument.asXML(),
81                      actualDocument.asXML());
82              }
83              catch (SAXException e) {
84                  throw new JellyTagException(e);
85              }
86              catch (IOException e) {
87                  throw new JellyTagException(e);
88              }
89              catch (ParserConfigurationException e) {
90                  throw new JellyTagException(e);
91              }
92  
93              if (delta.identical()) {
94                  return;
95              }
96              fail(delta.toString());
97          }
98      }
99  
100     /***
101      * Sets the actual XML document which is either a Document, String (of an
102      * URI), URI, Reader, or InputStream.
103      */
104     public void setActual(Object actual) {
105         this.actual = actual;
106     }
107 
108     /***
109      * Sets the expected XML document which is either a Document, String (of an
110      * URI), URI, Reader, or InputStream.
111      */
112     public void setExpected(Object expected) {
113         this.expected = expected;
114     }
115 
116     /***
117      * Controls whether whitespace differences should be interpreted as
118      * differences or not.  The default is <code>false</code>.  Note that the
119      * use of the <code>trim</code> attribute is crucial here.
120      */
121     public void setIgnoreWhitespace(boolean ignoreWhitespace) {
122         this.ignoreWhitespace = ignoreWhitespace;
123     }
124 
125     protected SAXReader createSAXReader() {
126         return new SAXReader();
127     }
128 
129 }