Source for gnu.xml.dom.DomNodeIterator

   1: /* DomNodeIterator.java -- 
   2:    Copyright (C) 2004 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: package gnu.xml.dom;
  38: 
  39: import org.w3c.dom.DOMException;
  40: import org.w3c.dom.Node;
  41: import org.w3c.dom.traversal.NodeFilter;
  42: import org.w3c.dom.traversal.NodeIterator;
  43: import org.w3c.dom.traversal.TreeWalker;
  44: 
  45: /**
  46:  * Node iterator and tree walker.
  47:  *
  48:  * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
  49:  */
  50: public class DomNodeIterator
  51:   implements NodeIterator, TreeWalker
  52: {
  53: 
  54:   Node root;
  55:   final int whatToShow;
  56:   final NodeFilter filter;
  57:   final boolean entityReferenceExpansion;
  58:   final boolean walk;
  59:   Node current;
  60: 
  61:   public DomNodeIterator(Node root, int whatToShow, NodeFilter filter,
  62:                          boolean entityReferenceExpansion, boolean walk)
  63:   {
  64:     if (root == null)
  65:       {
  66:         throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "null root");
  67:       }
  68:     this.root = root;
  69:     this.whatToShow = whatToShow;
  70:     this.filter = filter;
  71:     this.entityReferenceExpansion = entityReferenceExpansion;
  72:     this.walk = walk;
  73:     current = root;
  74:   }
  75: 
  76:   public Node getRoot()
  77:   {
  78:     return root;
  79:   }
  80: 
  81:   public int getWhatToShow()
  82:   {
  83:     return whatToShow;
  84:   }
  85: 
  86:   public NodeFilter getFilter()
  87:   {
  88:     return filter;
  89:   }
  90: 
  91:   public boolean getExpandEntityReferences()
  92:   {
  93:     return entityReferenceExpansion;
  94:   }
  95: 
  96:   public Node nextNode()
  97:     throws DOMException
  98:   {
  99:     if (root == null)
 100:       {
 101:         throw new DOMException(DOMException.INVALID_STATE_ERR, "null root");
 102:       }
 103:     Node ret;
 104:     do
 105:       {
 106:         if (current.equals(root))
 107:           {
 108:             ret = root.getFirstChild();
 109:           }
 110:         else if (walk)
 111:           {
 112:             ret = current.getFirstChild();
 113:             if (ret == null)
 114:               {
 115:                 ret = current.getNextSibling();
 116:               }
 117:             if (ret == null)
 118:               {
 119:                 Node tmp = current;
 120:                 ret = tmp.getParentNode();
 121:                 while (!ret.equals(root) && tmp.equals(ret.getLastChild()))
 122:                   {
 123:                     tmp = ret;
 124:                     ret = tmp.getParentNode();
 125:                   }
 126:                 if (ret.equals(root))
 127:                   {
 128:                     ret = null;
 129:                   }
 130:                 else
 131:                   {
 132:                     ret = ret.getNextSibling();
 133:                   }
 134:               }
 135:           }
 136:         else
 137:           {
 138:             ret = current.getNextSibling();
 139:           }
 140:       }
 141:     while (!accept(ret));
 142:     current = (ret == null) ? current : ret;
 143:     return ret;
 144:   }
 145: 
 146:   public Node previousNode()
 147:     throws DOMException
 148:   {
 149:     if (root == null)
 150:       {
 151:         throw new DOMException(DOMException.INVALID_STATE_ERR, "null root");
 152:       }
 153:     Node ret;
 154:     do
 155:       {
 156:         if (current.equals(root))
 157:           {
 158:             ret = current.getLastChild();
 159:           }
 160:         else if (walk)
 161:           {
 162:             ret = current.getLastChild();
 163:             if (ret == null)
 164:               {
 165:                 ret = current.getPreviousSibling();
 166:               }
 167:             if (ret == null)
 168:               {
 169:                 Node tmp = current;
 170:                 ret = tmp.getParentNode();
 171:                 while (!ret.equals(root) && tmp.equals(ret.getFirstChild()))
 172:                   {
 173:                     tmp = ret;
 174:                     ret = tmp.getParentNode();
 175:                   }
 176:                 if (ret.equals(root))
 177:                   {
 178:                     ret = null;
 179:                   }
 180:                 else
 181:                   {
 182:                     ret = ret.getPreviousSibling();
 183:                   }
 184:               }
 185:           }
 186:         else
 187:           {
 188:             ret = current.getPreviousSibling();
 189:           }
 190:       }
 191:     while (!accept(ret));
 192:     current = (ret == null) ? current : ret;
 193:     return ret;
 194:   }
 195: 
 196:   public Node getCurrentNode()
 197:   {
 198:     return current;
 199:   }
 200: 
 201:   public void setCurrentNode(Node current)
 202:     throws DOMException
 203:   {
 204:     if (current == null)
 205:       {
 206:         throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "null root");
 207:       }
 208:     this.current = current;
 209:   }
 210: 
 211:   public Node parentNode()
 212:   {
 213:     Node ret = current.getParentNode();
 214:     if (!accept (ret))
 215:       {
 216:         ret = null;
 217:       }
 218:     current = (ret == null) ? current : ret;
 219:     return ret;
 220:   }
 221: 
 222:   public Node firstChild ()
 223:   {
 224:     Node ret = current.getFirstChild();
 225:     while (!accept(ret))
 226:       {
 227:         ret = ret.getNextSibling();
 228:       }
 229:     current = (ret == null) ? current : ret;
 230:     return ret;
 231:   }
 232: 
 233:   public Node lastChild()
 234:   {
 235:     Node ret = current.getLastChild();
 236:     while (!accept(ret))
 237:       {
 238:         ret = ret.getPreviousSibling();
 239:       }
 240:     current = (ret == null) ? current : ret;
 241:     return ret;
 242:   }
 243: 
 244:   public Node previousSibling()
 245:   {
 246:     Node ret = current.getPreviousSibling();
 247:     while (!accept(ret))
 248:       {
 249:         ret = ret.getPreviousSibling();
 250:       }
 251:     current = (ret == null) ? current : ret;
 252:     return ret;
 253:   }
 254: 
 255:   public Node nextSibling()
 256:   {
 257:     Node ret = current.getNextSibling();
 258:     while (!accept(ret))
 259:       {
 260:         ret = ret.getNextSibling();
 261:       }
 262:     current = (ret == null) ? current : ret;
 263:     return ret;
 264:   }
 265: 
 266:   public void detach()
 267:   {
 268:     root = null;
 269:   }
 270: 
 271:   boolean accept(Node node)
 272:   {
 273:     if (node == null)
 274:       {
 275:         return true;
 276:       }
 277:     boolean ret;
 278:     switch (node.getNodeType())
 279:       {
 280:       case Node.ATTRIBUTE_NODE:
 281:         ret = (whatToShow & NodeFilter.SHOW_ATTRIBUTE) != 0;
 282:         break;
 283:       case Node.CDATA_SECTION_NODE:
 284:         ret = (whatToShow & NodeFilter.SHOW_CDATA_SECTION) != 0;
 285:         break;
 286:       case Node.COMMENT_NODE:
 287:         ret = (whatToShow & NodeFilter.SHOW_COMMENT) != 0;
 288:         break;
 289:       case Node.DOCUMENT_NODE:
 290:         ret = (whatToShow & NodeFilter.SHOW_DOCUMENT) != 0;
 291:         break;
 292:       case Node.DOCUMENT_FRAGMENT_NODE:
 293:         ret = (whatToShow & NodeFilter.SHOW_DOCUMENT_FRAGMENT) != 0;
 294:         break;
 295:       case Node.DOCUMENT_TYPE_NODE:
 296:         ret = (whatToShow & NodeFilter.SHOW_DOCUMENT_TYPE) != 0;
 297:         break;
 298:       case Node.ELEMENT_NODE:
 299:         ret = (whatToShow & NodeFilter.SHOW_ELEMENT) != 0;
 300:         break;
 301:       case Node.ENTITY_NODE:
 302:         ret = (whatToShow & NodeFilter.SHOW_ENTITY) != 0;
 303:         break;
 304:       case Node.ENTITY_REFERENCE_NODE:
 305:         ret = (whatToShow & NodeFilter.SHOW_ENTITY_REFERENCE) != 0;
 306:         ret = ret && entityReferenceExpansion;
 307:         break;
 308:       case Node.NOTATION_NODE:
 309:         ret = (whatToShow & NodeFilter.SHOW_NOTATION) != 0;
 310:         break;
 311:       case Node.PROCESSING_INSTRUCTION_NODE:
 312:         ret = (whatToShow & NodeFilter.SHOW_PROCESSING_INSTRUCTION) != 0;
 313:         break;
 314:       case Node.TEXT_NODE:
 315:         ret = (whatToShow & NodeFilter.SHOW_TEXT) != 0;
 316:         break;
 317:       default:
 318:         ret = true;
 319:       }
 320:     if (ret && filter != null)
 321:       {
 322:         ret = (filter.acceptNode(node) == NodeFilter.FILTER_ACCEPT);
 323:       }
 324:     return ret;
 325:   }
 326: 
 327: }