001 package net.sourceforge.pmd.lang.ast.xpath.saxon;
002
003 import net.sf.saxon.om.Axis;
004 import net.sf.saxon.om.AxisIterator;
005 import net.sf.saxon.om.DocumentInfo;
006 import net.sf.saxon.om.EmptyIterator;
007 import net.sf.saxon.om.Navigator;
008 import net.sf.saxon.om.NodeArrayIterator;
009 import net.sf.saxon.om.NodeInfo;
010 import net.sf.saxon.om.SingleNodeIterator;
011 import net.sf.saxon.type.Type;
012 import net.sourceforge.pmd.lang.ast.Node;
013
014 /**
015 * A Saxon OM Element type node for an AST Node.
016 */
017 public class ElementNode extends AbstractNodeInfo {
018
019 protected final DocumentNode document;
020 protected final ElementNode parent;
021 protected final Node node;
022 protected final int id;
023 protected final int siblingPosition;
024 protected final NodeInfo[] children;
025
026 public ElementNode(DocumentNode document, IdGenerator idGenerator, ElementNode parent, Node node,
027 int siblingPosition) {
028 this.document = document;
029 this.parent = parent;
030 this.node = node;
031 this.id = idGenerator.getNextId();
032 this.siblingPosition = siblingPosition;
033 if (node.jjtGetNumChildren() > 0) {
034 this.children = new NodeInfo[node.jjtGetNumChildren()];
035 for (int i = 0; i < children.length; i++) {
036 children[i] = new ElementNode(document, idGenerator, this, node.jjtGetChild(i), i);
037 }
038 } else {
039 this.children = null;
040 }
041 document.nodeToElementNode.put(node, this);
042 }
043
044 @Override
045 public Object getUnderlyingNode() {
046 return node;
047 }
048
049 @Override
050 public int getSiblingPosition() {
051 return siblingPosition;
052 }
053
054 @Override
055 public int getColumnNumber() {
056 return node.getBeginColumn();
057 }
058
059 @Override
060 public int getLineNumber() {
061 return node.getBeginLine();
062 }
063
064 @Override
065 public boolean hasChildNodes() {
066 return children != null;
067 }
068
069 @Override
070 public int getNodeKind() {
071 return Type.ELEMENT;
072 }
073
074 @Override
075 public DocumentInfo getDocumentRoot() {
076 return document;
077 }
078
079 @Override
080 public String getLocalPart() {
081 return node.toString();
082 }
083
084 @Override
085 public String getURI() {
086 return "";
087 }
088
089 @Override
090 public NodeInfo getParent() {
091 return parent;
092 }
093
094 @Override
095 public int compareOrder(NodeInfo other) {
096 return Integer.signum(this.node.jjtGetId() - ((ElementNode) other).node.jjtGetId());
097 }
098
099 @SuppressWarnings("PMD.MissingBreakInSwitch")
100 @Override
101 public AxisIterator iterateAxis(byte axisNumber) {
102 switch (axisNumber) {
103 case Axis.ANCESTOR:
104 return new Navigator.AncestorEnumeration(this, false);
105 case Axis.ANCESTOR_OR_SELF:
106 return new Navigator.AncestorEnumeration(this, true);
107 case Axis.ATTRIBUTE:
108 return new AttributeAxisIterator(this);
109 case Axis.CHILD:
110 if (children == null) {
111 return EmptyIterator.getInstance();
112 } else {
113 return new NodeArrayIterator(children);
114 }
115 case Axis.DESCENDANT:
116 return new Navigator.DescendantEnumeration(this, false, true);
117 case Axis.DESCENDANT_OR_SELF:
118 return new Navigator.DescendantEnumeration(this, true, true);
119 case Axis.FOLLOWING:
120 return new Navigator.FollowingEnumeration(this);
121 case Axis.FOLLOWING_SIBLING:
122 if (parent == null || siblingPosition == parent.children.length - 1) {
123 return EmptyIterator.getInstance();
124 } else {
125 return new NodeArrayIterator(parent.children, siblingPosition, parent.children.length);
126 }
127 case Axis.NAMESPACE:
128 return super.iterateAxis(axisNumber);
129 case Axis.PARENT:
130 return SingleNodeIterator.makeIterator(parent);
131 case Axis.PRECEDING:
132 return new Navigator.PrecedingEnumeration(this, false);
133 case Axis.PRECEDING_SIBLING:
134 if (parent == null || siblingPosition == 0) {
135 return EmptyIterator.getInstance();
136 } else {
137 return new NodeArrayIterator(parent.children, 0, siblingPosition);
138 }
139 case Axis.SELF:
140 return SingleNodeIterator.makeIterator(this);
141 case Axis.PRECEDING_OR_ANCESTOR:
142 return new Navigator.PrecedingEnumeration(this, true);
143 default:
144 return super.iterateAxis(axisNumber);
145 }
146 }
147
148 }
|