001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.xpath.pattern;
030:
031: import org.w3c.dom.Node;
032:
033: /**
034: * Represents a selected node.
035: */
036: public class SelectedNode {
037: protected Node _node;
038:
039: protected int _depth;
040: protected int _level;
041:
042: /**
043: * Creates new selected node, calculating the index.
044: *
045: * @param node the underlying DOM node.
046: */
047: public SelectedNode(Node node) {
048: _node = node;
049:
050: _depth = 0;
051: for (Node ptr = node; ptr != null; ptr = ptr.getParentNode()) {
052: _depth++;
053: }
054:
055: _level = 0;
056: for (Node ptr = node; ptr != null; ptr = ptr
057: .getPreviousSibling()) {
058: _level++;
059: }
060: }
061:
062: /**
063: * Returns the underlying DOM node.
064: */
065: public Node getNode() {
066: return _node;
067: }
068:
069: /**
070: * Returns the node's index
071: */
072: public int compareTo(SelectedNode b) {
073: int aDepth = _depth;
074: int bDepth = b._depth;
075:
076: Node aPtr = getNode();
077: Node bPtr = b.getNode();
078:
079: if (aDepth == bDepth
080: && aPtr.getParentNode() == bPtr.getParentNode())
081: return _level - b._level;
082:
083: return compareTo(aPtr, aDepth, bPtr, bDepth);
084: }
085:
086: /**
087: * Returns the node's index
088: */
089: static int compareTo(Node aPtr, int aDepth, Node bPtr, int bDepth) {
090: for (int depth = aDepth; bDepth < depth; depth--)
091: aPtr = aPtr.getParentNode();
092:
093: for (int depth = bDepth; aDepth < depth; depth--)
094: bPtr = bPtr.getParentNode();
095:
096: Node aParent;
097: Node bParent;
098: while ((aParent = aPtr.getParentNode()) != (bParent = bPtr
099: .getParentNode())) {
100: aPtr = aParent;
101: bPtr = bParent;
102: }
103:
104: if (aPtr == bPtr)
105: return aDepth - bDepth;
106:
107: for (; aPtr != null; aPtr = aPtr.getPreviousSibling()) {
108: if (aPtr == bPtr)
109: return 1;
110: }
111:
112: return -1;
113: }
114: }
|