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: import org.w3c.dom.Attr;
040: import org.w3c.dom.DocumentType;
041: import org.w3c.dom.Node;
042: import org.w3c.dom.ProcessingInstruction;
043:
044: /**
045: * Class for describing Nodes
046: */
047: public class NodeDescriptor implements XMLConstants {
048: protected static final String DOCUMENT_NODE_DESCRIPTION = "Document Node ";
049:
050: /**
051: * Convert a Node into a simple String representation
052: * and append to StringBuffer
053: * @param buf
054: * @param aNode
055: */
056: public static void appendNodeDetail(StringBuffer buf,
057: NodeDetail nodeDetail) {
058: appendNodeDetail(buf, nodeDetail.getNode(), true);
059: buf.append(" at ").append(nodeDetail.getXpathLocation());
060: }
061:
062: private static void appendNodeDetail(StringBuffer buf, Node aNode,
063: boolean notRecursing) {
064: if (aNode == null) {
065: return;
066: }
067: if (notRecursing) {
068: buf.append(XMLConstants.OPEN_START_NODE);
069: }
070: switch (aNode.getNodeType()) {
071: case Node.ATTRIBUTE_NODE:
072: appendAttributeDetail(buf, aNode);
073: break;
074: case Node.ELEMENT_NODE:
075: appendElementDetail(buf, aNode, notRecursing);
076: break;
077: case Node.TEXT_NODE:
078: appendTextDetail(buf, aNode);
079: break;
080: case Node.CDATA_SECTION_NODE:
081: appendCdataSectionDetail(buf, aNode);
082: break;
083: case Node.COMMENT_NODE:
084: appendCommentDetail(buf, aNode);
085: break;
086: case Node.PROCESSING_INSTRUCTION_NODE:
087: appendProcessingInstructionDetail(buf, aNode);
088: break;
089: case Node.DOCUMENT_TYPE_NODE:
090: appendDocumentTypeDetail(buf, aNode);
091: break;
092: case Node.DOCUMENT_NODE:
093: appendDocumentDetail(buf);
094: break;
095: default:
096: buf.append("!--NodeType ").append(aNode.getNodeType())
097: .append(' ').append(aNode.getNodeName())
098: .append('/').append(aNode.getNodeValue()).append(
099: "--");
100:
101: }
102: if (notRecursing) {
103: buf.append(XMLConstants.CLOSE_NODE);
104: }
105: }
106:
107: protected static void appendDocumentDetail(StringBuffer buf) {
108: buf.append(DOCUMENT_NODE_DESCRIPTION).append(
109: XMLConstants.OPEN_START_NODE).append("...").append(
110: XMLConstants.CLOSE_NODE);
111: }
112:
113: protected static void appendDocumentTypeDetail(StringBuffer buf,
114: Node aNode) {
115: DocumentType type = (DocumentType) aNode;
116: buf.append(XMLConstants.START_DOCTYPE).append(type.getName());
117: boolean hasNoPublicId = true;
118: if (type.getPublicId() != null
119: && type.getPublicId().length() > 0) {
120: buf.append(" PUBLIC \"").append(type.getPublicId()).append(
121: '"');
122: hasNoPublicId = false;
123: }
124: if (type.getSystemId() != null
125: && type.getSystemId().length() > 0) {
126: if (hasNoPublicId) {
127: buf.append(" SYSTEM");
128: }
129: buf.append(" \"").append(type.getSystemId()).append('"');
130: }
131: }
132:
133: protected static void appendProcessingInstructionDetail(
134: StringBuffer buf, Node aNode) {
135: ProcessingInstruction instr = (ProcessingInstruction) aNode;
136: buf.append(XMLConstants.START_PROCESSING_INSTRUCTION).append(
137: instr.getTarget()).append(' ').append(instr.getData())
138: .append(XMLConstants.END_PROCESSING_INSTRUCTION);
139: }
140:
141: protected static void appendCommentDetail(StringBuffer buf,
142: Node aNode) {
143: buf.append(XMLConstants.START_COMMENT).append(
144: aNode.getNodeValue()).append(XMLConstants.END_COMMENT);
145: }
146:
147: protected static void appendCdataSectionDetail(StringBuffer buf,
148: Node aNode) {
149: buf.append(XMLConstants.START_CDATA).append(
150: aNode.getNodeValue()).append(XMLConstants.END_CDATA);
151: }
152:
153: protected static void appendTextDetail(StringBuffer buf, Node aNode) {
154: appendNodeDetail(buf, aNode.getParentNode(), false);
155: buf.append(" ...").append(XMLConstants.CLOSE_NODE).append(
156: aNode.getNodeValue())
157: .append(XMLConstants.OPEN_END_NODE);
158: appendNodeDetail(buf, aNode.getParentNode(), false);
159: }
160:
161: protected static void appendElementDetail(StringBuffer buf,
162: Node aNode, boolean notRecursing) {
163: buf.append(aNode.getNodeName());
164: if (notRecursing) {
165: buf.append("...");
166: }
167: }
168:
169: protected static void appendAttributeDetail(StringBuffer buf,
170: Node aNode) {
171: appendNodeDetail(buf, ((Attr) aNode).getOwnerElement(), false);
172: buf.append(' ').append(aNode.getNodeName()).append("=\"")
173: .append(aNode.getNodeValue()).append("\"...");
174: }
175: }
|