1
2
3
4 package net.sourceforge.pmd.lang.ast.xpath.saxon;
5
6 import net.sf.saxon.om.Axis;
7 import net.sf.saxon.om.AxisIterator;
8 import net.sf.saxon.om.DocumentInfo;
9 import net.sf.saxon.om.EmptyIterator;
10 import net.sf.saxon.om.Navigator;
11 import net.sf.saxon.om.NodeArrayIterator;
12 import net.sf.saxon.om.NodeInfo;
13 import net.sf.saxon.om.SingleNodeIterator;
14 import net.sf.saxon.type.Type;
15 import net.sourceforge.pmd.lang.ast.Node;
16
17
18
19
20 public class ElementNode extends AbstractNodeInfo {
21
22 protected final DocumentNode document;
23 protected final ElementNode parent;
24 protected final Node node;
25 protected final int id;
26 protected final int siblingPosition;
27 protected final NodeInfo[] children;
28
29 public ElementNode(DocumentNode document, IdGenerator idGenerator, ElementNode parent, Node node,
30 int siblingPosition) {
31 this.document = document;
32 this.parent = parent;
33 this.node = node;
34 this.id = idGenerator.getNextId();
35 this.siblingPosition = siblingPosition;
36 if (node.jjtGetNumChildren() > 0) {
37 this.children = new NodeInfo[node.jjtGetNumChildren()];
38 for (int i = 0; i < children.length; i++) {
39 children[i] = new ElementNode(document, idGenerator, this, node.jjtGetChild(i), i);
40 }
41 } else {
42 this.children = null;
43 }
44 document.nodeToElementNode.put(node, this);
45 }
46
47 @Override
48 public Object getUnderlyingNode() {
49 return node;
50 }
51
52 @Override
53 public int getSiblingPosition() {
54 return siblingPosition;
55 }
56
57 @Override
58 public int getColumnNumber() {
59 return node.getBeginColumn();
60 }
61
62 @Override
63 public int getLineNumber() {
64 return node.getBeginLine();
65 }
66
67 @Override
68 public boolean hasChildNodes() {
69 return children != null;
70 }
71
72 @Override
73 public int getNodeKind() {
74 return Type.ELEMENT;
75 }
76
77 @Override
78 public DocumentInfo getDocumentRoot() {
79 return document;
80 }
81
82 @Override
83 public String getLocalPart() {
84 return node.toString();
85 }
86
87 @Override
88 public String getURI() {
89 return "";
90 }
91
92 @Override
93 public NodeInfo getParent() {
94 return parent;
95 }
96
97 @Override
98 public int compareOrder(NodeInfo other) {
99 return Integer.signum(this.node.jjtGetId() - ((ElementNode) other).node.jjtGetId());
100 }
101
102 @SuppressWarnings("PMD.MissingBreakInSwitch")
103 @Override
104 public AxisIterator iterateAxis(byte axisNumber) {
105 switch (axisNumber) {
106 case Axis.ANCESTOR:
107 return new Navigator.AncestorEnumeration(this, false);
108 case Axis.ANCESTOR_OR_SELF:
109 return new Navigator.AncestorEnumeration(this, true);
110 case Axis.ATTRIBUTE:
111 return new AttributeAxisIterator(this);
112 case Axis.CHILD:
113 if (children == null) {
114 return EmptyIterator.getInstance();
115 } else {
116 return new NodeArrayIterator(children);
117 }
118 case Axis.DESCENDANT:
119 return new Navigator.DescendantEnumeration(this, false, true);
120 case Axis.DESCENDANT_OR_SELF:
121 return new Navigator.DescendantEnumeration(this, true, true);
122 case Axis.FOLLOWING:
123 return new Navigator.FollowingEnumeration(this);
124 case Axis.FOLLOWING_SIBLING:
125 if (parent == null || siblingPosition == parent.children.length - 1) {
126 return EmptyIterator.getInstance();
127 } else {
128 return new NodeArrayIterator(parent.children, siblingPosition + 1, parent.children.length);
129 }
130 case Axis.NAMESPACE:
131 return super.iterateAxis(axisNumber);
132 case Axis.PARENT:
133 return SingleNodeIterator.makeIterator(parent);
134 case Axis.PRECEDING:
135 return new Navigator.PrecedingEnumeration(this, false);
136 case Axis.PRECEDING_SIBLING:
137 if (parent == null || siblingPosition == 0) {
138 return EmptyIterator.getInstance();
139 } else {
140 return new NodeArrayIterator(parent.children, 0, siblingPosition);
141 }
142 case Axis.SELF:
143 return SingleNodeIterator.makeIterator(this);
144 case Axis.PRECEDING_OR_ANCESTOR:
145 return new Navigator.PrecedingEnumeration(this, true);
146 default:
147 return super.iterateAxis(axisNumber);
148 }
149 }
150
151 }