1 package net.sourceforge.pmd.lang.ast.xpath.saxon;
2
3 import net.sf.saxon.om.Axis;
4 import net.sf.saxon.om.AxisIterator;
5 import net.sf.saxon.om.DocumentInfo;
6 import net.sf.saxon.om.EmptyIterator;
7 import net.sf.saxon.om.Navigator;
8 import net.sf.saxon.om.NodeArrayIterator;
9 import net.sf.saxon.om.NodeInfo;
10 import net.sf.saxon.om.SingleNodeIterator;
11 import net.sf.saxon.type.Type;
12 import net.sourceforge.pmd.lang.ast.Node;
13
14
15
16
17 public class ElementNode extends AbstractNodeInfo {
18
19 protected final DocumentNode document;
20 protected final ElementNode parent;
21 protected final Node node;
22 protected final int id;
23 protected final int siblingPosition;
24 protected final NodeInfo[] children;
25
26 public ElementNode(DocumentNode document, IdGenerator idGenerator, ElementNode parent, Node node,
27 int siblingPosition) {
28 this.document = document;
29 this.parent = parent;
30 this.node = node;
31 this.id = idGenerator.getNextId();
32 this.siblingPosition = siblingPosition;
33 if (node.jjtGetNumChildren() > 0) {
34 this.children = new NodeInfo[node.jjtGetNumChildren()];
35 for (int i = 0; i < children.length; i++) {
36 children[i] = new ElementNode(document, idGenerator, this, node.jjtGetChild(i), i);
37 }
38 } else {
39 this.children = null;
40 }
41 document.nodeToElementNode.put(node, this);
42 }
43
44 @Override
45 public Object getUnderlyingNode() {
46 return node;
47 }
48
49 @Override
50 public int getSiblingPosition() {
51 return siblingPosition;
52 }
53
54 @Override
55 public int getColumnNumber() {
56 return node.getBeginColumn();
57 }
58
59 @Override
60 public int getLineNumber() {
61 return node.getBeginLine();
62 }
63
64 @Override
65 public boolean hasChildNodes() {
66 return children != null;
67 }
68
69 @Override
70 public int getNodeKind() {
71 return Type.ELEMENT;
72 }
73
74 @Override
75 public DocumentInfo getDocumentRoot() {
76 return document;
77 }
78
79 @Override
80 public String getLocalPart() {
81 return node.toString();
82 }
83
84 @Override
85 public String getURI() {
86 return "";
87 }
88
89 @Override
90 public NodeInfo getParent() {
91 return parent;
92 }
93
94 @Override
95 public int compareOrder(NodeInfo other) {
96 return Integer.signum(this.node.jjtGetId() - ((ElementNode) other).node.jjtGetId());
97 }
98
99 @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 }