KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > xml > QNode


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.xml;
30
31 import com.caucho.xpath.pattern.NodeListIterator;
32
33 import org.w3c.dom.DOMException JavaDoc;
34 import org.w3c.dom.NamedNodeMap JavaDoc;
35 import org.w3c.dom.Node JavaDoc;
36 import org.w3c.dom.NodeList JavaDoc;
37
38 import java.util.Iterator JavaDoc;
39
40 /**
41  * QNode represents any node that can have children.
42  */

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 JavaDoc getNodeValue() { return null; }
57
58   public void setNodeValue(String JavaDoc value) {}
59
60   /**
61    * Returns a node list of the children.
62    */

63   public NodeList JavaDoc getChildNodes()
64   {
65     return new ChildNodeList();
66   }
67
68   public Node JavaDoc getFirstChild()
69   {
70     return _firstChild;
71   }
72
73   public Node JavaDoc getLastChild()
74   {
75     return _lastChild;
76   }
77
78   public Node JavaDoc getPreviousSibling()
79   {
80     return _previous;
81   }
82
83   public Node JavaDoc getNextSibling()
84   {
85     return _next;
86   }
87
88   public NamedNodeMap JavaDoc getAttributes() { return null; }
89
90   public Node JavaDoc insertBefore(Node JavaDoc newChild, Node JavaDoc refChild)
91     throws DOMException JavaDoc
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 JavaDoc replaceChild(Node JavaDoc newChild, Node JavaDoc refChild)
146     throws DOMException JavaDoc
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 JavaDoc removeChild(Node JavaDoc oldChild) throws DOMException JavaDoc
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 JavaDoc 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 JavaDoc appendChild(Node JavaDoc newNode) throws DOMException JavaDoc
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 JavaDoc 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 JavaDoc
289   {
290     if (! super.checkValid())
291       throw new Exception JavaDoc("super bad: " + this);
292
293     if (_firstChild != null && _firstChild._previous != null)
294       throw new Exception JavaDoc("first child bad: " + this);
295
296     if (_lastChild != null && _lastChild._next != null)
297       throw new Exception JavaDoc("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 JavaDoc("child parent bad:" + this + " " + ptr);
303       if (ptr._owner != _owner && ptr._owner != this)
304         throw new Exception JavaDoc("child owner bad:" + this + " " + ptr + " " +
305                             ptr._owner + " " + _owner);
306       if (ptr._next != null && ptr._next._previous != ptr)
307         throw new Exception JavaDoc("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 JavaDoc("child parent bad:" + this + " " + ptr);
314       if (ptr._owner != _owner && ptr._owner != this)
315         throw new Exception JavaDoc("child owner bad:" + this + " " + ptr);
316       if (ptr._previous != null && ptr._previous._next != ptr)
317         throw new Exception JavaDoc("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 JavaDoc arg)
339   {
340     return this == arg;
341   }
342
343   public boolean equals(Node JavaDoc arg, boolean deep)
344   {
345     return this == arg;
346   }
347
348   // NodeList methods
349

350   public class ChildNodeList implements NodeList JavaDoc {
351     /**
352      * Returns the child with the given index.
353      */

354     public Node JavaDoc 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     /**
365      * Returns the number of children.
366      */

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     // for quercus
377
public Iterator<Node JavaDoc> iterator()
378     {
379       return new NodeListIterator(null, this);
380     }
381   }
382 }
383
Popular Tags