XMLPos.java

Go to the documentation of this file.
00001 
00002 //
00003 // XML storage classes version 1.5
00004 //
00005 // XMLPos.java
00006 //
00007 // Copyright (c) 2004, 2005, 2007, 2010 Martin Fuchs <martin-fuchs@gmx.net>
00008 //
00009 
00010 
00011 /*
00012 
00013  All rights reserved.
00014 
00015  Redistribution and use in source and binary forms, with or without
00016  modification, are permitted provided that the following conditions are met:
00017 
00018  * Redistributions of source code must retain the above copyright
00019     notice, this list of conditions and the following disclaimer.
00020  * Redistributions in binary form must reproduce the above copyright
00021     notice, this list of conditions and the following disclaimer in
00022     the documentation and/or other materials provided with the
00023     distribution.
00024 
00025  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00026  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00028  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00029  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00030  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00031  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00032  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00033  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00034  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  POSSIBILITY OF SUCH DAMAGE.
00036 
00037 */
00038 
00039 package de.mfuchs.xmlstorage;
00040 
00041 import java.util.Stack;
00042 
00043 
00044 /**
00045  * XMLPos is the iterator for XML trees in XMLStorage.
00046  * @author Martin Fuchs
00047  */
00048 public class XMLPos
00049 {
00050     /**
00051      * Construct an XMLPos, which points to the given XMLNode. 
00052      * @param root root node
00053      */
00054     public XMLPos(XMLNode root)
00055     {
00056         _root = root;
00057         _cur = root;
00058     }
00059 
00060     /**
00061      * Construct an XMLPos as copy of another.
00062      * @param other XMLPos original
00063      */
00064     public XMLPos(final XMLPos other)
00065     {
00066         _root = other._root;
00067         _cur = other._cur;
00068         // don't copy _stack
00069     }
00070 
00071     /**
00072      * Create XML tree iterator positioned at subnode node_name of current other position.
00073      * @param other position to be copied
00074      * @param nodeName new node name
00075      */
00076     public XMLPos(final XMLPos other, final String nodeName)
00077     {
00078         _root = other._root;
00079         _cur = other._cur;
00080         // don't copy _stack
00081         smartCreate(nodeName);
00082     }
00083 
00084     /**
00085      * Create XML tree iterator positioned at subnode node_name
00086      * with attribute attrName and attribute value attrValue.
00087      * @see XMLPos.smart_create
00088      * @param other position to be copied
00089      * @param nodeName new node name
00090      * @param attrName attribute name
00091      * @param attrValue attribute value
00092      */
00093     public XMLPos(final XMLPos other, final String nodeName, final String attrName, final String attrValue)
00094     {
00095         _root = other._root;
00096         _cur = other._cur;
00097         // don't copy _stack
00098         smartCreate(nodeName, attrName, attrValue);
00099     }
00100 
00101     /**
00102      * Return the current node.
00103      * @return current position
00104      */
00105     public XMLNode cur()
00106     {
00107         return _cur;
00108     }
00109 
00110     /**
00111      * Return the value of an attribute in the current node or "".
00112      * @param attrName attribute name
00113      * @return attribute value
00114      */
00115     public String get(final String attrName)
00116     {
00117         return _cur.get(attrName);
00118     }
00119 
00120     /**
00121      * Return the value of an attribute in the current node or a default value.
00122      * @param attrName attribute name
00123      * @param def default value
00124      * @return value
00125      */
00126     public String get(final String attrName, final String def)
00127     {
00128         return _cur.get(attrName, def);
00129     }
00130 
00131     /**
00132      * Set an attribute value.
00133      * @param attrName attribute name
00134      * @param value new attribute value
00135      */
00136     public void put(final String attrName, final String value)
00137     {
00138         _cur.put(attrName, value);
00139     }
00140 
00141     /**
00142      * Insert children when building tree.
00143      * @param child new child
00144      */
00145     public void addDown(XMLNode child)
00146     {
00147         _cur.addChild(child);
00148         goTo(child);
00149     }
00150 
00151     /**
00152      * Go back to previous position.
00153      * @return true if successfull
00154      */
00155     public boolean back()
00156     {
00157         if (!_stack.empty()) {
00158             _cur = _stack.pop();
00159             return true;
00160         } else
00161             return false;
00162     }
00163 
00164     /**
00165      * Go down to first child.
00166      * @return true if successfull
00167      */
00168     public boolean goDown()
00169     {
00170         XMLNode node = _cur.getFirstChild();
00171 
00172         if (node != null) {
00173             goTo(node);
00174             return true;
00175         } else
00176             return false;
00177     }
00178 
00179     /**
00180      * Search for child and go down.
00181      * @param name node name
00182      * @return true if successfull
00183      */
00184     public boolean goDown(final String name)
00185     {
00186         XMLNode node = _cur.find(name);
00187 
00188         if (node != null) {
00189             goTo(node);
00190             return true;
00191         } else
00192             return false;
00193     }
00194 
00195     /**
00196      * Move X-Path like to position in XML tree.
00197      * @param path XPath expression
00198      * @return true if successfull
00199      */
00200     public boolean go(String path)
00201     {
00202         return go(new XPath(path));
00203     }
00204 
00205     /**
00206      * Move X-Path like to position in XML tree.
00207      * @param xpath XPath object
00208      * @return true if successfull
00209      */
00210     public boolean go(XPath xpath)
00211     {
00212         XMLNode node = xpath._absolute? _root: _cur;
00213 
00214         node = node.findRelative(xpath);
00215 
00216         if (node != null) {
00217             goTo(node);
00218             return true;
00219         } else
00220             return false;
00221     }
00222 
00223     /**
00224      * Create node and move to it.
00225      * @param name name of the new node
00226      */
00227     public void create(final String name)
00228     {
00229         addDown(new XMLNode(name));
00230     }
00231 
00232     /**
00233      * Create node if not already existing and move to it.
00234      * @param name name of the new node
00235      */
00236     public void smartCreate(final String name)
00237     {
00238         XMLNode node = _cur.find(name);
00239 
00240         if (node != null)
00241             goTo(node);
00242         else
00243             addDown(new XMLNode(name));
00244     }
00245 
00246     /**
00247      * Search matching child node identified by key name and an attribute value.
00248      * It it doesn't exist, create it.
00249      * @param name name of the new node
00250      * @param attrName attribute name
00251      * @param attrValue attribute value
00252      */
00253     public void smartCreate(final String name, final String attrName, final String attrValue)
00254     {
00255         XMLNode node = _cur.find(name, attrName, attrValue);
00256 
00257         if (node != null)
00258             goTo(node);
00259         else {
00260             node = new XMLNode(name);
00261             addDown(node);
00262             node.put(attrName, attrValue);
00263         }
00264     }
00265 
00266     /**
00267      * @return content string
00268      */
00269     public String getContent()
00270     {
00271         return _cur.getContent();
00272     }
00273 
00274     /**
00275      * @param s new content string
00276      */
00277     public void setContent(final String s)
00278     {
00279         setContent(s, false);
00280     }
00281 
00282     /**
00283      * @param s new content string
00284      * @param cdata write in CDATA format if true
00285      */
00286     public void setContent(final String s, boolean cdata)
00287     {
00288         _cur.setContent(s, cdata);
00289     }
00290 
00291     /**
00292      * Return the name oif the current node.
00293      */
00294     public String toString()
00295     {
00296         return _cur.toString();
00297     }
00298 
00299     protected XMLNode   _root;
00300     protected XMLNode   _cur;
00301     protected Stack<XMLNode> _stack = new Stack<XMLNode>();
00302 
00303     /**
00304      * Go to the specified node.
00305      * @param child new position
00306      */
00307     protected void goTo(XMLNode child)
00308     {
00309         _stack.push(_cur);
00310         _cur = child;
00311     }
00312 
00313     /**
00314      * Set an attribute in a subnode.
00315      * @param nodeName node name
00316      * @param attrName attribute name
00317      * @param value attribute value
00318      */
00319     public void putSubattrib(final String nodeName, final String attrName, final String value)
00320     {
00321         _cur.putSubattrib(nodeName, attrName, value);
00322     }
00323 }