Home | History | Annotate | Download | only in kdom
      1 /* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
      2  *
      3  * Permission is hereby granted, free of charge, to any person obtaining a copy
      4  * of this software and associated documentation files (the "Software"), to deal
      5  * in the Software without restriction, including without limitation the rights
      6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or
      7  * sell copies of the Software, and to permit persons to whom the Software is
      8  * furnished to do so, subject to the following conditions:
      9  *
     10  * The  above copyright notice and this permission notice shall be included in
     11  * all copies or substantial portions of the Software.
     12  *
     13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     19  * IN THE SOFTWARE. */
     20 
     21 package org.ksoap2.kdom;
     22 
     23 import java.io.*;
     24 import java.util.*;
     25 
     26 import org.xmlpull.v1.*;
     27 
     28 /**
     29  * In order to create an element, please use the createElement method
     30  * instead of invoking the constructor directly. The right place to
     31  * add user defined initialization code is the init method. */
     32 
     33 public class Element extends Node {
     34 
     35     protected String namespace;
     36     protected String name;
     37     protected Vector attributes;
     38     protected Node parent;
     39     protected Vector prefixes;
     40 
     41     public Element() {
     42     }
     43 
     44     /**
     45      * called when all properties are set, but before children
     46      * are parsed. Please do not use setParent for initialization
     47      * code any longer. */
     48 
     49     public void init() {
     50     }
     51 
     52     /**
     53      * removes all children and attributes */
     54 
     55     public void clear() {
     56         attributes = null;
     57         children = null;
     58     }
     59 
     60     /**
     61      * Forwards creation request to parent if any, otherwise
     62      * calls super.createElement. */
     63 
     64     public Element createElement(
     65             String namespace,
     66             String name) {
     67 
     68         return (this.parent == null)
     69                 ? super.createElement(namespace, name)
     70                 : this.parent.createElement(namespace, name);
     71     }
     72 
     73     /**
     74      * Returns the number of attributes of this element. */
     75 
     76     public int getAttributeCount() {
     77         return attributes == null ? 0 : attributes.size();
     78     }
     79 
     80     public String getAttributeNamespace(int index) {
     81         return ((String[]) attributes.elementAt(index))[0];
     82     }
     83 
     84     /*    public String getAttributePrefix (int index) {
     85             return ((String []) attributes.elementAt (index)) [1];
     86         }*/
     87 
     88     public String getAttributeName(int index) {
     89         return ((String[]) attributes.elementAt(index))[1];
     90     }
     91 
     92     public String getAttributeValue(int index) {
     93         return ((String[]) attributes.elementAt(index))[2];
     94     }
     95 
     96     public String getAttributeValue(String namespace, String name) {
     97         for (int i = 0; i < getAttributeCount(); i++) {
     98             if (name.equals(getAttributeName(i))
     99                     && (namespace == null || namespace.equals(getAttributeNamespace(i)))) {
    100                 return getAttributeValue(i);
    101             }
    102         }
    103         return null;
    104     }
    105 
    106     /**
    107      * Returns the root node, determined by ascending to the
    108      * all parents un of the root element. */
    109 
    110     public Node getRoot() {
    111 
    112         Element current = this;
    113 
    114         while (current.parent != null) {
    115             if (!(current.parent instanceof Element))
    116                 return current.parent;
    117             current = (Element) current.parent;
    118         }
    119 
    120         return current;
    121     }
    122 
    123     /**
    124      * returns the (local) name of the element */
    125 
    126     public String getName() {
    127         return name;
    128     }
    129 
    130     /**
    131      * returns the namespace of the element */
    132 
    133     public String getNamespace() {
    134         return namespace;
    135     }
    136 
    137     /**
    138      * returns the namespace for the given prefix */
    139 
    140     public String getNamespaceUri(String prefix) {
    141         int cnt = getNamespaceCount();
    142         for (int i = 0; i < cnt; i++) {
    143             if (prefix == getNamespacePrefix(i) ||
    144                     (prefix != null && prefix.equals(getNamespacePrefix(i))))
    145                 return getNamespaceUri(i);
    146         }
    147         return parent instanceof Element ? ((Element) parent).getNamespaceUri(prefix) : null;
    148     }
    149 
    150     /**
    151      * returns the number of declared namespaces, NOT including
    152      * parent elements */
    153 
    154     public int getNamespaceCount() {
    155         return (prefixes == null ? 0 : prefixes.size());
    156     }
    157 
    158     public String getNamespacePrefix(int i) {
    159         return ((String[]) prefixes.elementAt(i))[0];
    160     }
    161 
    162     public String getNamespaceUri(int i) {
    163         return ((String[]) prefixes.elementAt(i))[1];
    164     }
    165 
    166     /**
    167      * Returns the parent node of this element */
    168 
    169     public Node getParent() {
    170         return parent;
    171     }
    172 
    173     /*
    174      * Returns the parent element if available, null otherwise
    175 
    176     public Element getParentElement() {
    177         return (parent instanceof Element)
    178             ? ((Element) parent)
    179             : null;
    180     }
    181     */
    182 
    183     /**
    184      * Builds the child elements from the given Parser. By overwriting
    185      * parse, an element can take complete control over parsing its
    186      * subtree. */
    187 
    188     public void parse(XmlPullParser parser)
    189             throws IOException, XmlPullParserException {
    190 
    191         for (int i = parser.getNamespaceCount(parser.getDepth() - 1); i < parser
    192                 .getNamespaceCount(parser.getDepth()); i++) {
    193             setPrefix(parser.getNamespacePrefix(i), parser.getNamespaceUri(i));
    194         }
    195 
    196         for (int i = 0; i < parser.getAttributeCount(); i++)
    197             setAttribute(parser.getAttributeNamespace(i),
    198                     //                          parser.getAttributePrefix (i),
    199                     parser.getAttributeName(i),
    200                     parser.getAttributeValue(i));
    201 
    202         //        if (prefixMap == null) throw new RuntimeException ("!!");
    203 
    204         init();
    205 
    206         if (parser.isEmptyElementTag())
    207             parser.nextToken();
    208         else {
    209             parser.nextToken();
    210             super.parse(parser);
    211 
    212             if (getChildCount() == 0)
    213                 addChild(IGNORABLE_WHITESPACE, "");
    214         }
    215 
    216         parser.require(
    217                 XmlPullParser.END_TAG,
    218                 getNamespace(),
    219                 getName());
    220 
    221         parser.nextToken();
    222     }
    223 
    224     /**
    225      * Sets the given attribute; a value of null removes the attribute */
    226 
    227     public void setAttribute(String namespace, String name, String value) {
    228         if (attributes == null)
    229             attributes = new Vector();
    230 
    231         if (namespace == null)
    232             namespace = "";
    233 
    234         for (int i = attributes.size() - 1; i >= 0; i--) {
    235             String[] attribut = (String[]) attributes.elementAt(i);
    236             if (attribut[0].equals(namespace) &&
    237                     attribut[1].equals(name)) {
    238 
    239                 if (value == null) {
    240                     attributes.removeElementAt(i);
    241                 }
    242                 else {
    243                     attribut[2] = value;
    244                 }
    245                 return;
    246             }
    247         }
    248 
    249         attributes.addElement
    250                 (new String[] {
    251                         namespace, name, value
    252                 });
    253     }
    254 
    255     /**
    256      * Sets the given prefix; a namespace value of null removess the
    257      * prefix */
    258 
    259     public void setPrefix(String prefix, String namespace) {
    260         if (prefixes == null)
    261             prefixes = new Vector();
    262         prefixes.addElement(new String[] {
    263                 prefix, namespace
    264         });
    265     }
    266 
    267     /**
    268      * sets the name of the element */
    269 
    270     public void setName(String name) {
    271         this.name = name;
    272     }
    273 
    274     /**
    275      * sets the namespace of the element. Please note: For no
    276      * namespace, please use Xml.NO_NAMESPACE, null is not a legal
    277      * value. Currently, null is converted to Xml.NO_NAMESPACE, but
    278      * future versions may throw an exception. */
    279 
    280     public void setNamespace(String namespace) {
    281         if (namespace == null)
    282             throw new NullPointerException("Use \"\" for empty namespace");
    283         this.namespace = namespace;
    284     }
    285 
    286     /**
    287      * Sets the Parent of this element. Automatically called from the
    288      * add method.  Please use with care, you can simply
    289      * create inconsitencies in the document tree structure using
    290      * this method!  */
    291 
    292     protected void setParent(Node parent) {
    293         this.parent = parent;
    294     }
    295 
    296     /**
    297      * Writes this element and all children to the given XmlWriter. */
    298 
    299     public void write(XmlSerializer writer)
    300             throws IOException {
    301 
    302         if (prefixes != null) {
    303             for (int i = 0; i < prefixes.size(); i++) {
    304                 writer.setPrefix(getNamespacePrefix(i), getNamespaceUri(i));
    305             }
    306         }
    307 
    308         writer.startTag(
    309                 getNamespace(),
    310                 getName());
    311 
    312         int len = getAttributeCount();
    313 
    314         for (int i = 0; i < len; i++) {
    315             writer.attribute(
    316                     getAttributeNamespace(i),
    317                     getAttributeName(i),
    318                     getAttributeValue(i));
    319         }
    320 
    321         writeChildren(writer);
    322 
    323         writer.endTag(getNamespace(), getName());
    324     }
    325 }
    326