001: /*
002: ******************************************************************
003: Copyright (c) 2006-2007, Jeff Martin, Tim Bacon
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: * Redistributions of source code must retain the above copyright
011: notice, this list of conditions and the following disclaimer.
012: * Redistributions in binary form must reproduce the above
013: copyright notice, this list of conditions and the following
014: disclaimer in the documentation and/or other materials provided
015: with the distribution.
016: * Neither the name of the xmlunit.sourceforge.net nor the names
017: of its contributors may be used to endorse or promote products
018: derived from this software without specific prior written
019: permission.
020:
021: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
022: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
023: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
024: FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
025: COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
026: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
027: BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
028: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
029: CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
030: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
031: ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
032: POSSIBILITY OF SUCH DAMAGE.
033:
034: ******************************************************************
035: */
036:
037: package org.custommonkey.xmlunit.examples;
038:
039: import org.w3c.dom.Element;
040: import org.w3c.dom.Node;
041:
042: import org.custommonkey.xmlunit.ElementNameAndTextQualifier;
043: import org.custommonkey.xmlunit.ElementNameQualifier;
044: import org.custommonkey.xmlunit.ElementQualifier;
045:
046: /**
047: * Per popular request an interface implementation that uses element
048: * names and the text node containes in the n'th child node to compare
049: * elements.
050: *
051: * <p>This means {@link ElementNameAndTextQualifier
052: * ElementNameQualifier} and MultiLevelElementNameQualifier(1) should
053: * lead to the same results.</p>
054: *
055: * <p>Any attribute values ar completely ignored. Only works on
056: * elements with exactly one child element at each level.</p>
057: *
058: * <p>This class mostly exists as an example for custom ElementQualifiers.</p>
059: */
060: public class MultiLevelElementNameAndTextQualifier implements
061: ElementQualifier {
062:
063: private final int levels;
064:
065: private static final ElementNameQualifier NAME_QUALIFIER = new ElementNameQualifier();
066: private static final ElementNameAndTextQualifier NAME_AND_TEXT_QUALIFIER = new ElementNameAndTextQualifier();
067:
068: /**
069: * Uses element names and the text nested <code>levels</code>
070: * child elements deeper into the element to compare elements.
071: */
072: public MultiLevelElementNameAndTextQualifier(int levels) {
073: if (levels < 1) {
074: throw new IllegalArgumentException(
075: "levels must be equal or" + " greater than one");
076: }
077: this .levels = levels;
078: }
079:
080: public boolean qualifyForComparison(Element control, Element test) {
081: boolean stillSimilar = true;
082: Element currentControl = control;
083: Element currentTest = test;
084:
085: // match on element names only for leading levels
086: for (int currentLevel = 0; stillSimilar
087: && currentLevel <= levels - 2; currentLevel++) {
088: stillSimilar = NAME_QUALIFIER.qualifyForComparison(
089: currentControl, currentTest);
090: if (stillSimilar) {
091: if (currentControl.hasChildNodes()
092: && currentTest.hasChildNodes()) {
093: Node n1 = currentControl.getFirstChild();
094: Node n2 = currentTest.getFirstChild();
095: if (n1.getNodeType() == Node.ELEMENT_NODE
096: && n2.getNodeType() == Node.ELEMENT_NODE) {
097: currentControl = (Element) n1;
098: currentTest = (Element) n2;
099: } else {
100: stillSimilar = false;
101: }
102: } else {
103: stillSimilar = false;
104: }
105: }
106: }
107:
108: // finally compare the level containing the text child node
109: if (stillSimilar) {
110: stillSimilar = NAME_AND_TEXT_QUALIFIER
111: .qualifyForComparison(currentControl, currentTest);
112: }
113:
114: return stillSimilar;
115: }
116:
117: }
|