1 28 29 package com.caucho.xml; 30 31 import com.caucho.xpath.pattern.NodeListIterator; 32 33 import org.w3c.dom.DOMException ; 34 import org.w3c.dom.NamedNodeMap ; 35 import org.w3c.dom.Node ; 36 import org.w3c.dom.NodeList ; 37 38 import java.util.Iterator ; 39 40 43 public abstract class QNode extends QAbstractNode { 44 protected QAbstractNode _firstChild; 45 protected QAbstractNode _lastChild; 46 47 protected QNode() 48 { 49 } 50 51 protected QNode(QDocument owner) 52 { 53 super(owner); 54 } 55 56 public String getNodeValue() { return null; } 57 58 public void setNodeValue(String value) {} 59 60 63 public NodeList getChildNodes() 64 { 65 return new ChildNodeList(); 66 } 67 68 public Node getFirstChild() 69 { 70 return _firstChild; 71 } 72 73 public Node getLastChild() 74 { 75 return _lastChild; 76 } 77 78 public Node getPreviousSibling() 79 { 80 return _previous; 81 } 82 83 public Node getNextSibling() 84 { 85 return _next; 86 } 87 88 public NamedNodeMap getAttributes() { return null; } 89 90 public Node insertBefore(Node newChild, Node refChild) 91 throws DOMException 92 { 93 QAbstractNode qNewChild = (QAbstractNode) newChild; 94 QAbstractNode qRefChild = (QAbstractNode) refChild; 95 96 if (qNewChild._owner != _owner && qNewChild._owner != this) 97 throw new QDOMException(DOMException.WRONG_DOCUMENT_ERR, 98 "insertBefore new child from wrong document"); 99 100 qNewChild.remove(); 101 102 if (qRefChild != null && qRefChild._parent != this) 103 throw new QDOMException(DOMException.NOT_FOUND_ERR, "insertBefore has no such child"); 104 105 if (qNewChild instanceof QDocumentFragment) { 106 QDocumentFragment frag = (QDocumentFragment) qNewChild; 107 QAbstractNode first = frag._firstChild; 108 QAbstractNode next = null; 109 for (QAbstractNode ptr = first; ptr != null; ptr = next) { 110 next = ptr._next; 111 insertBefore(ptr, refChild); 112 } 113 114 return first; 115 } 116 117 qNewChild._parent = this; 118 119 if (refChild == null) { 120 if (_firstChild == null) { 121 qNewChild._previous = null; 122 qNewChild._next = null; 123 _firstChild = _lastChild = qNewChild; 124 } else { 125 _lastChild._next = qNewChild; 126 qNewChild._previous = _lastChild; 127 _lastChild = qNewChild; 128 qNewChild._next = null; 129 } 130 131 return qNewChild; 132 } 133 134 qNewChild._previous = qRefChild._previous; 135 qNewChild._next = qRefChild; 136 if (qRefChild._previous == null) 137 _firstChild = qNewChild; 138 else 139 qRefChild._previous._next = qNewChild; 140 qRefChild._previous = qNewChild; 141 142 return qNewChild; 143 } 144 145 public Node replaceChild(Node newChild, Node refChild) 146 throws DOMException 147 { 148 QAbstractNode qNewChild = (QAbstractNode) newChild; 149 QAbstractNode qRefChild = (QAbstractNode) refChild; 150 151 if (qRefChild == null || qRefChild._parent != this) 152 throw new QDOMException(DOMException.NOT_FOUND_ERR, "ref is not child"); 153 154 if (qNewChild == null || qNewChild._owner != _owner) 155 throw new QDOMException(DOMException.WRONG_DOCUMENT_ERR, 156 "wrong document"); 157 158 if (_owner != null) 159 _owner._changeCount++; 160 161 qNewChild._previous = qRefChild._previous; 162 qNewChild._next = qRefChild._next; 163 qNewChild._parent = this; 164 165 if (qNewChild._previous == null) 166 _firstChild = qNewChild; 167 else 168 qNewChild._previous._next = qNewChild; 169 170 if (qNewChild._next == null) 171 _lastChild = qNewChild; 172 else 173 qNewChild._next._previous = qNewChild; 174 175 qRefChild._previous = null; 176 qRefChild._next = null; 177 qRefChild._parent = null; 178 179 return qRefChild; 180 } 181 182 public Node removeChild(Node oldChild) throws DOMException 183 { 184 QAbstractNode qOldChild = (QAbstractNode) oldChild; 185 186 if (qOldChild != null && qOldChild._parent != this) { 187 throw new QDOMException(DOMException.NOT_FOUND_ERR, 188 "removeChild has no such child"); 189 } 190 191 if (_owner != null) 192 _owner._changeCount++; 193 194 if (qOldChild._previous == null) 195 _firstChild = qOldChild._next; 196 else 197 qOldChild._previous._next = qOldChild._next; 198 199 if (qOldChild._next == null) 200 _lastChild = qOldChild._previous; 201 else 202 qOldChild._next._previous = qOldChild._previous; 203 204 qOldChild._parent = null; 205 qOldChild._next = null; 206 qOldChild._previous = null; 207 208 return qOldChild; 209 } 210 211 private static void setOwner(QAbstractNode node, QDocument owner) 212 { 213 if (node._owner == null) { 214 node._owner = owner; 215 216 String namespace = node.getNamespaceURI(); 217 218 if (namespace != "") 219 owner.addNamespace(node.getPrefix(), namespace); 220 221 for (QAbstractNode child = (QAbstractNode) node.getFirstChild(); 222 child != null; 223 child = (QAbstractNode) child.getNextSibling()) 224 { 225 setOwner(child, owner); 226 } 227 } 228 } 229 230 public Node appendChild(Node newNode) throws DOMException 231 { 232 QAbstractNode qNewNode = (QAbstractNode) newNode; 233 234 setOwner(qNewNode, _owner); 235 236 if (qNewNode._owner != _owner && qNewNode._owner != this) { 237 throw new QDOMException(DOMException.WRONG_DOCUMENT_ERR, 238 "can't appendChild from different document"); 239 } 240 241 qNewNode.remove(); 242 243 if (qNewNode instanceof QDocumentFragment) { 244 QDocumentFragment frag = (QDocumentFragment) qNewNode; 245 QAbstractNode first = frag._firstChild; 246 QAbstractNode next = null; 247 for (QAbstractNode ptr = first; ptr != null; ptr = next) { 248 next = ptr._next; 249 appendChild(ptr); 250 } 251 252 return first; 253 } 254 255 qNewNode._parent = this; 256 qNewNode._next = null; 257 qNewNode._previous = _lastChild; 258 if (_lastChild == null) { 259 _lastChild = qNewNode; 260 _firstChild = qNewNode; 261 } 262 else { 263 _lastChild._next = qNewNode; 264 _lastChild = qNewNode; 265 } 266 267 return qNewNode; 268 } 269 270 public boolean hasChildNodes() 271 { 272 return _firstChild != null; 273 } 274 275 public void setTextContent(String content) 276 { 277 QText text = new QText(content); 278 text._owner = _owner; 279 280 _firstChild = _lastChild = text; 281 } 282 283 public void normalize() 284 { 285 } 286 287 public boolean checkValid() 288 throws Exception 289 { 290 if (! super.checkValid()) 291 throw new Exception ("super bad: " + this); 292 293 if (_firstChild != null && _firstChild._previous != null) 294 throw new Exception ("first child bad: " + this); 295 296 if (_lastChild != null && _lastChild._next != null) 297 throw new Exception ("last child bad:" + this); 298 299 QAbstractNode ptr = _firstChild; 300 for (; ptr != null; ptr = ptr._next) { 301 if (ptr._parent != this) 302 throw new Exception ("child parent bad:" + this + " " + ptr); 303 if (ptr._owner != _owner && ptr._owner != this) 304 throw new Exception ("child owner bad:" + this + " " + ptr + " " + 305 ptr._owner + " " + _owner); 306 if (ptr._next != null && ptr._next._previous != ptr) 307 throw new Exception ("child links bad:" + this + " " + ptr); 308 } 309 310 ptr = _lastChild; 311 for (; ptr != null; ptr = ptr._previous) { 312 if (ptr._parent != this) 313 throw new Exception ("child parent bad:" + this + " " + ptr); 314 if (ptr._owner != _owner && ptr._owner != this) 315 throw new Exception ("child owner bad:" + this + " " + ptr); 316 if (ptr._previous != null && ptr._previous._next != ptr) 317 throw new Exception ("child links bad:" + this + " " + ptr); 318 } 319 320 return true; 321 } 322 323 public QAbstractNode getNextPreorder() 324 { 325 if (_firstChild != null) 326 return _firstChild; 327 else if (_next != null) 328 return _next; 329 330 for (QNode ptr = _parent; ptr != null; ptr = ptr._parent) { 331 if (ptr._next != null) 332 return ptr._next; 333 } 334 335 return null; 336 } 337 338 public boolean equals(Object arg) 339 { 340 return this == arg; 341 } 342 343 public boolean equals(Node arg, boolean deep) 344 { 345 return this == arg; 346 } 347 348 350 public class ChildNodeList implements NodeList { 351 354 public Node item(int index) 355 { 356 QAbstractNode ptr = _firstChild; 357 for (; ptr != null && index > 0; index--) { 358 ptr = ptr._next; 359 } 360 361 return ptr; 362 } 363 364 367 public int getLength() 368 { 369 int index = 0; 370 for (QAbstractNode ptr = _firstChild; ptr != null; ptr = ptr._next) 371 index++; 372 373 return index; 374 } 375 376 public Iterator<Node > iterator() 378 { 379 return new NodeListIterator(null, this); 380 } 381 } 382 } 383 | Popular Tags |