001: /*
002: ******************************************************************
003: Copyright (c) 2001-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;
038:
039: /**
040: * Value object that describes a difference between DOM Nodes using one of
041: * the DifferenceConstants ID values and a NodeDetail instance.
042: * <br />Examples and more at <a href="http://xmlunit.sourceforge.net"/>xmlunit.sourceforge.net</a>
043: * @see NodeDetail
044: */
045: public class Difference {
046: /** Simple unique identifier */
047: private final int id;
048: /** Description of the difference */
049: private final String description;
050: /** TRUE if the difference represents a similarity, FALSE otherwise */
051: private boolean recoverable;
052:
053: private NodeDetail controlNodeDetail = null;
054: private NodeDetail testNodeDetail = null;
055:
056: /**
057: * Constructor for non-similar Difference instances
058: * @param id
059: * @param description
060: */
061: protected Difference(int id, String description) {
062: this (id, description, false);
063: }
064:
065: /**
066: * Constructor for similar Difference instances
067: * @param id
068: * @param description
069: */
070: protected Difference(int id, String description, boolean recoverable) {
071: this .id = id;
072: this .description = description;
073: this .recoverable = recoverable;
074: }
075:
076: /**
077: * Copy constructor using prototype Difference and
078: * encountered NodeDetails
079: */
080: protected Difference(Difference prototype,
081: NodeDetail controlNodeDetail, NodeDetail testNodeDetail) {
082: this (prototype.getId(), prototype.getDescription(), prototype
083: .isRecoverable());
084: this .controlNodeDetail = controlNodeDetail;
085: this .testNodeDetail = testNodeDetail;
086: }
087:
088: /**
089: * @return the id
090: */
091: public int getId() {
092: return id;
093: }
094:
095: /**
096: * @return the description
097: */
098: public String getDescription() {
099: return description;
100: }
101:
102: /**
103: * @return TRUE if the difference represents a similarity, FALSE otherwise
104: */
105: public boolean isRecoverable() {
106: return recoverable;
107: }
108:
109: /**
110: * Allow the recoverable field value to be overridden.
111: * Used when an override DifferenceListener is used in conjunction with
112: * a DetailedDiff.
113: */
114: protected void setRecoverable(boolean overrideValue) {
115: recoverable = overrideValue;
116: }
117:
118: /**
119: * @return the NodeDetail from the piece of XML used as the control
120: * at the Node where this difference was encountered
121: */
122: public NodeDetail getControlNodeDetail() {
123: return controlNodeDetail;
124: }
125:
126: /**
127: * @return the NodeDetail from the piece of XML used as the test
128: * at the Node where this difference was encountered
129: */
130: public NodeDetail getTestNodeDetail() {
131: return testNodeDetail;
132: }
133:
134: /**
135: * Now that Differences can be constructed from prototypes
136: * we need to be able to compare them to those in DifferenceConstants
137: */
138: public boolean equals(Object other) {
139: if (other == null) {
140: return false;
141: } else if (other instanceof Difference) {
142: Difference otherDifference = (Difference) other;
143: return id == otherDifference.getId();
144: } else {
145: return false;
146: }
147: }
148:
149: /**
150: * hashcode implementation to go with equals.
151: */
152: public int hashCode() {
153: return id;
154: }
155:
156: /**
157: * @return a basic representation of the object state and identity
158: * and if <code>NodeDetail</code> instances are populated append
159: * their details also
160: */
161: public String toString() {
162: StringBuffer buf = new StringBuffer();
163: if (controlNodeDetail == null || testNodeDetail == null) {
164: appendBasicRepresentation(buf);
165: } else {
166: appendDetailedRepresentation(buf);
167: }
168: return buf.toString();
169: }
170:
171: private void appendBasicRepresentation(StringBuffer buf) {
172: buf.append("Difference (#").append(id).append(") ").append(
173: description);
174: }
175:
176: private void appendDetailedRepresentation(StringBuffer buf) {
177: buf.append("Expected ").append(getDescription()).append(" '")
178: .append(controlNodeDetail.getValue()).append(
179: "' but was '")
180: .append(testNodeDetail.getValue()).append(
181: "' - comparing ");
182: NodeDescriptor.appendNodeDetail(buf, controlNodeDetail);
183: buf.append(" to ");
184: NodeDescriptor.appendNodeDetail(buf, testNodeDetail);
185: }
186:
187: }
|