001 /* 002 * Created on Apr 3, 2009 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 * 014 * Copyright @2009 the original author or authors. 015 */ 016 package org.fest.swing.junit.xml; 017 018 import static org.fest.util.Objects.HASH_CODE_PRIME; 019 import static org.fest.util.Objects.hashCodeFor; 020 import static org.fest.util.Strings.concat; 021 022 import org.w3c.dom.*; 023 024 /** 025 * Understands a DOM-based XML element. This class is intended for internal use only. It is just a thin wrapper around 026 * a DOM <code>{@link Element}</code>. It only provides the necessary functionality needed by the FEST-Swing JUnit 027 * extension. 028 * 029 * @author Alex Ruiz 030 */ 031 public class XmlNode { 032 033 private final Element target; 034 035 /** 036 * Creates a new </code>{@link XmlNode}</code>. 037 * @param target the underlying DOM element. 038 */ 039 protected XmlNode(Element target) { 040 this.target = target; 041 } 042 043 /** 044 * Creates and adds a new XML node to this node. 045 * @param name the name of the node to add. 046 * @return the created node. 047 */ 048 public XmlNode addNewNode(String name) { 049 return new XmlNode(createAndAddChild(name)); 050 } 051 052 /** 053 * Creates and adds a new XML node to this node. 054 * @param name the name of the node to add. 055 * @param attributes the attributes of the node to add. 056 * @return the created node. 057 */ 058 public XmlNode addNewNode(String name, XmlAttributes attributes) { 059 Element e = createAndAddChild(name); 060 for (XmlAttribute a : attributes) addAttribute(e, a); 061 return new XmlNode(e); 062 } 063 064 private Element createAndAddChild(String name) { 065 Element e = document().createElement(name); 066 target.appendChild(e); 067 return e; 068 } 069 070 /** 071 * Adds a CDATA section to this node. 072 * @param data the data for the CDATA section to create. 073 */ 074 public void addCdata(String data) { 075 CDATASection s = document().createCDATASection(data); 076 target.appendChild(s); 077 } 078 079 /** 080 * Adds a text node to this node. 081 * @param text the text of the new text node. 082 */ 083 public void addText(String text) { 084 Text textNode = document().createTextNode(text); 085 target.appendChild(textNode); 086 } 087 088 private Document document() { 089 return target.getOwnerDocument(); 090 } 091 092 /** 093 * Adds an attribute to this node. 094 * @param a the attribute to add. 095 */ 096 public void addAttribute(XmlAttribute a) { 097 addAttribute(target, a); 098 } 099 100 /** 101 * Adds one or more attributes to this node. 102 * @param attributes the attribute(s) to add to this node. 103 */ 104 public void addAttributes(XmlAttribute...attributes) { 105 for (XmlAttribute a : attributes) addAttribute(target, a); 106 } 107 108 private static void addAttribute(Element e, XmlAttribute a) { 109 e.setAttribute(a.name(), a.value()); 110 } 111 112 /** 113 * Returns the underlying DOM <code>{@link Element}</code>. 114 * @return the underlying DOM element. 115 */ 116 public Element target() { return target; } 117 118 /** 119 * Returns the parent node of this node. 120 * @return the parent node of this node. 121 */ 122 public XmlNode parentNode() { 123 return xmlNodeFrom(target.getParentNode()); 124 } 125 126 /** 127 * Returns the number of children in this node. 128 * @return the number of children in this node. 129 */ 130 public int size() { 131 return target.getChildNodes().getLength(); 132 } 133 134 /** 135 * Returns the child at the given index. 136 * @param index the given index. 137 * @return the child at the given index. 138 */ 139 public XmlNode child(int index) { 140 return xmlNodeFrom(target.getChildNodes().item(index)); 141 } 142 143 private static XmlNode xmlNodeFrom(Node n) { 144 if (!(n instanceof Element)) return null; 145 return new XmlNode((Element)n); 146 } 147 148 /** 149 * Returns the value of the given attribute, or an empty <code>String</code> if this node does not contain an 150 * attribute with the given name. 151 * @param name the name of the attribute we are looking for. 152 * @return the value of the attribute with the given name, or an empty <code>String</code> if this node does not 153 * contain a matching attribute. 154 */ 155 public String valueOfAttribute(String name) { 156 return target.getAttribute(name); 157 } 158 159 /** 160 * Returns the name of this node. 161 * @return the name of this node. 162 */ 163 public String name() { 164 return target.getNodeName(); 165 } 166 167 /** 168 * Returns the text content of this node. 169 * @return the text content of this node. 170 */ 171 public String text() { 172 return target.getTextContent(); 173 } 174 175 /** 176 * Returns the number of attributes in this node. 177 * @return the number of attributes in this node. 178 */ 179 public int attributeCount() { 180 return target.getAttributes().getLength(); 181 } 182 183 @Override public boolean equals(Object obj) { 184 if (this == obj) return true; 185 if (obj == null) return false; 186 if (getClass() != obj.getClass()) return false; 187 XmlNode other = (XmlNode) obj; 188 return target.isEqualNode(other.target); 189 } 190 191 @Override public int hashCode() { 192 int result = 1; 193 result = HASH_CODE_PRIME * result + hashCodeFor(name()); 194 return result; 195 } 196 197 @Override public String toString() { 198 return concat( 199 getClass().getSimpleName(), "[", 200 "target=", target, "]" 201 ); 202 } 203 }