KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.CharBuffer;
32
33 import org.w3c.dom.*;
34
35 import java.io.IOException JavaDoc;
36 import java.util.HashMap JavaDoc;
37
38 /**
39  * Resin's implementation of the DOM element.
40  */

41 public class QElement extends QAttributedNode implements CauchoElement {
42   private QName _name;
43
44   /**
45    * Create a new element.
46    */

47   public QElement()
48   {
49   }
50
51   /**
52    * Create a new named element.
53    *
54    * @param name the element's name.
55    */

56   public QElement(String JavaDoc name)
57   {
58     _name = new QName(name);
59   }
60
61   /**
62    * Create a new named element.
63    *
64    * @param name the element's name.
65    */

66   public QElement(String JavaDoc name, String JavaDoc namespace)
67   {
68     _name = new QName(name, namespace);
69   }
70
71   /**
72    * Create a new named element.
73    *
74    * @param name the element's name.
75    */

76   public QElement(QName name)
77   {
78     _name = name;
79   }
80
81   protected QElement(QDocument owner, QName name)
82   {
83     _owner = owner;
84     _name = name;
85   }
86
87   /**
88    * Create a new named element with initial parameters.
89    *
90    * @param name the element's name.
91    * @param attributes the element's attributes.
92    */

93   QElement(QName name, HashMap JavaDoc attributes)
94   {
95     _name = name;
96   }
97
98   /**
99    * Assign a name to the element. Not normally called by external
100    * API.
101    *
102    * @param name the element's name.
103    */

104   public void setName(QName name)
105   {
106     _name = name;
107   }
108
109   /**
110    * Returns the qname
111    */

112   public QName getQName()
113   {
114     return _name;
115   }
116
117   /**
118    * Returns the element's qualified-name as the node name.
119    */

120   public String JavaDoc getNodeName()
121   {
122     return _name.getName();
123   }
124
125   /**
126    * Returns the element's qualified-name as the node name.
127    */

128   public String JavaDoc getTagName()
129   {
130     return _name.getName();
131   }
132
133   /**
134    * Returns the local part of the element's name.
135    */

136   public String JavaDoc getLocalName()
137   {
138     return _name.getLocalName();
139   }
140
141   /**
142    * Returns the namespace prefix for the element.
143    */

144   public String JavaDoc getPrefix()
145   {
146     return _name.getPrefix();
147   }
148
149   /**
150    * Returns the canonical name of the element.
151    */

152   public String JavaDoc getCanonicalName()
153   {
154     return _name.getCanonicalName();
155   }
156
157   /**
158    * Returns the namespace of the element.
159    */

160   public String JavaDoc getNamespaceURI()
161   {
162     return _name.getNamespace();
163   }
164
165   /**
166    * Given a prefix, returns the namespace in effect at this element.
167    *
168    * @param prefix the prefix to test.
169    * @return the namespace URL matching the prefix or null.
170    */

171   public String JavaDoc getNamespace(String JavaDoc prefix)
172   {
173     if (prefix == null)
174       return getNamespace("", "xmlns");
175     else
176       return getNamespace(prefix, "xmlns:" + prefix);
177   }
178
179   private String JavaDoc getNamespace(String JavaDoc prefix, String JavaDoc xmlns)
180   {
181     Attr namespace = getAttributeNode(xmlns);
182
183     if (namespace != null)
184       return namespace.getNodeValue();
185
186     if (_parent instanceof QElement)
187       return ((QElement) _parent).getNamespace(prefix, xmlns);
188
189     return _owner.getNamespace(prefix);
190   }
191
192   /**
193    * Returns the DOM NodeType, ELEMENT_NODE.
194    */

195   public short getNodeType()
196   {
197     return ELEMENT_NODE;
198   }
199
200   /**
201    * Returns the schema type.
202    */

203   public TypeInfo getSchemaTypeInfo()
204   {
205     return null;
206   }
207
208   /**
209    * Returns a list of elements, given a tag name.
210    */

211   public NodeList getElementsByTagName(String JavaDoc tagName)
212   {
213     QAbstractNode child = (QAbstractNode) getFirstChild();
214     
215     if (child != null)
216       return new QDeepNodeList(this, child, new TagPredicate(tagName));
217     else
218       return new QDeepNodeList(this, null, new TagPredicate(tagName));
219   }
220   
221   /**
222    * Returns a list of elements, given a namespace and a local name.
223    */

224   public NodeList getElementsByTagNameNS(String JavaDoc uri, String JavaDoc name)
225   {
226     QAbstractNode child = (QAbstractNode) getFirstChild();
227     
228     if (child != null)
229       return new QDeepNodeList(this, child, new NSTagPredicate(uri, name));
230     else
231       return new QDeepNodeList(this, null, new NSTagPredicate(uri, name));
232   }
233
234   /**
235    * Appends a new node as the last child of the element.
236    *
237    * @param child the new child.
238    * @return the child.
239    */

240   public Node appendChild(Node child)
241     throws DOMException
242   {
243     Node result = super.appendChild(child);
244
245     if (child instanceof QElement) {
246       QElement elt = (QElement) child;
247       QName name = elt._name;
248
249       if (name.getNamespace() != "") {
250         addNamespace(name);
251       }
252
253       for (QAttr attr = (QAttr) elt.getFirstAttribute();
254        attr != null;
255        attr = (QAttr) attr.getNextSibling()) {
256     name = attr._name;
257
258     if (name.getNamespace() != "") {
259       addNamespace(name);
260     }
261       }
262     }
263
264     return result;
265   }
266
267   /**
268    * Adds the name to the global namespace, if possible.
269    */

270   void addNamespace(QName name)
271   {
272     _owner.addNamespace(name.getPrefix(), name.getNamespace());
273   }
274
275   /**
276    * Normalize the element, i.e. smash all neighboring text nodes together.
277    */

278   public void normalize()
279   {
280     Node node = _firstChild;
281
282     while (node != null) {
283       if (node.getNodeType() == TEXT_NODE &&
284       node.getNextSibling() != null &&
285       node.getNextSibling().getNodeType() == TEXT_NODE) {
286     Text text = (Text) node;
287     Text next = (Text) node.getNextSibling();
288     text.appendData(next.getData());
289     removeChild(next);
290       } else if (node.getNodeType() == ELEMENT_NODE) {
291     Element elt = (Element) node;
292     elt.normalize();
293     node = node.getNextSibling();
294       } else
295     node = node.getNextSibling();
296     }
297   }
298
299   public boolean hasContent()
300   {
301     return true;
302   }
303
304   public boolean equals(Object JavaDoc arg)
305   {
306     return this == arg;
307   }
308
309   public boolean equals(Node arg, boolean deep)
310   {
311     return this == arg;
312   }
313
314   /**
315    * Returns the text value of the element. For an element, the text
316    * value is the smashing together of all the child text nodes.
317    */

318   public String JavaDoc getTextValue()
319   {
320     CharBuffer cb = CharBuffer.allocate();
321
322     for (QAbstractNode node = _firstChild; node != null; node = node._next) {
323       cb.append(node.getTextValue());
324     }
325
326     return cb.close();
327   }
328
329   void print(XmlPrinter out) throws IOException JavaDoc
330   {
331     out.startElement(getNamespaceURI(), getLocalName(), getNodeName());
332     for (QAbstractNode node = (QAbstractNode) getFirstAttribute();
333          node != null;
334          node = (QAbstractNode) node.getNextSibling()) {
335       out.attribute(node.getNamespaceURI(),
336                     node.getLocalName(),
337                     node.getNodeName(),
338                     node.getNodeValue());
339     }
340     for (Node node = getFirstChild();
341          node != null;
342          node = node.getNextSibling()) {
343       ((QAbstractNode) node).print(out);
344     }
345     out.endElement(getNamespaceURI(), getLocalName(), getNodeName());
346   }
347
348   public String JavaDoc toString()
349   {
350     CharBuffer cb = CharBuffer.allocate();
351
352     cb.append("Element[" + _name);
353
354     for (QAttr attr = (QAttr) getFirstAttribute();
355          attr != null;
356          attr = (QAttr) attr.getNextSibling())
357       cb.append(" " + attr);
358     cb.append("]");
359
360     return cb.close();
361   }
362
363   private Object JavaDoc writeReplace()
364   {
365     return new SerializedXml(this);
366   }
367
368   static class TagPredicate implements QNodePredicate {
369     String JavaDoc _name;
370
371     TagPredicate(String JavaDoc name)
372     {
373       if (name == null)
374         name = "*";
375       
376       _name = name;
377     }
378
379     public boolean isMatch(QAbstractNode node)
380     {
381       return (node.getNodeName().equals(_name) ||
382               _name.equals("*") && node instanceof Element);
383     }
384   }
385
386   static class NSTagPredicate implements QNodePredicate {
387     String JavaDoc _uri;
388     String JavaDoc _local;
389
390     NSTagPredicate(String JavaDoc uri, String JavaDoc local)
391     {
392       _uri = uri;
393       _local = local;
394     }
395
396     public boolean isMatch(QAbstractNode node)
397     {
398       return (_local.equals(node.getLocalName()) &&
399               _uri.equals(node.getNamespaceURI()));
400     }
401   }
402 }
403
Popular Tags