1 /***
2 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 */
4 package net.sourceforge.pmd.jaxen;
5
6 import net.sourceforge.pmd.ast.CompilationUnit;
7 import net.sourceforge.pmd.ast.Node;
8 import org.jaxen.DefaultNavigator;
9 import org.jaxen.XPath;
10 import org.jaxen.util.SingleObjectIterator;
11
12 import java.util.ArrayList;
13 import java.util.Iterator;
14
15 /***
16 * @author daniels
17 */
18 public class DocumentNavigator extends DefaultNavigator {
19
20 private final static Iterator EMPTY_ITERATOR = new ArrayList().iterator();
21
22 public String getAttributeName(Object arg0) {
23 return ((Attribute) arg0).getName();
24 }
25
26 public String getAttributeNamespaceUri(Object arg0) {
27 return "";
28 }
29
30 public String getAttributeQName(Object arg0) {
31 return ((Attribute) arg0).getName();
32 }
33
34 public String getAttributeStringValue(Object arg0) {
35 return ((Attribute) arg0).getValue();
36 }
37
38 public String getCommentStringValue(Object arg0) {
39 return "";
40 }
41
42 public String getElementName(Object node) {
43 return node.toString();
44 }
45
46 public String getElementNamespaceUri(Object arg0) {
47 return "";
48 }
49
50 public String getElementQName(Object arg0) {
51 return getElementName(arg0);
52 }
53
54 public String getElementStringValue(Object arg0) {
55 return "";
56 }
57
58 public String getNamespacePrefix(Object arg0) {
59 return "";
60 }
61
62 public String getNamespaceStringValue(Object arg0) {
63 return "";
64 }
65
66 public String getTextStringValue(Object arg0) {
67 return "";
68 }
69
70 public boolean isAttribute(Object arg0) {
71 return arg0 instanceof Attribute;
72 }
73
74 public boolean isComment(Object arg0) {
75 return false;
76 }
77
78 public boolean isDocument(Object arg0) {
79 return arg0 instanceof CompilationUnit;
80 }
81
82 public boolean isElement(Object arg0) {
83 return arg0 instanceof Node;
84 }
85
86 public boolean isNamespace(Object arg0) {
87 return false;
88 }
89
90 public boolean isProcessingInstruction(Object arg0) {
91 return false;
92 }
93
94 public boolean isText(Object arg0) {
95 return false;
96 }
97
98 public XPath parseXPath(String arg0) {
99 return null;
100 }
101
102 public Object getParentNode(Object arg0) {
103 if (arg0 instanceof Node) {
104 return ((Node) arg0).jjtGetParent();
105 }
106 return ((Attribute) arg0).getParent();
107 }
108
109 public Iterator getAttributeAxisIterator(Object arg0) {
110 return new AttributeAxisIterator((Node) arg0);
111 }
112
113 /***
114 * Get an iterator over all of this node's children.
115 *
116 * @param contextNode The context node for the child axis.
117 * @return A possibly-empty iterator (not null).
118 */
119 public Iterator getChildAxisIterator(Object contextNode) {
120 return new NodeIterator((Node) contextNode) {
121 protected Node getFirstNode(Node node) {
122 return getFirstChild(node);
123 }
124
125 protected Node getNextNode(Node node) {
126 return getNextSibling(node);
127 }
128 };
129 }
130
131 /***
132 * Get a (single-member) iterator over this node's parent.
133 *
134 * @param contextNode the context node for the parent axis.
135 * @return A possibly-empty iterator (not null).
136 */
137 public Iterator getParentAxisIterator(Object contextNode) {
138 if (isAttribute(contextNode)) {
139 return new SingleObjectIterator(((Attribute) contextNode).getParent());
140 }
141 Node parent = ((Node) contextNode).jjtGetParent();
142 if (parent != null) {
143 return new SingleObjectIterator(parent);
144 } else {
145 return EMPTY_ITERATOR;
146 }
147 }
148
149 /***
150 * Get an iterator over all following siblings.
151 *
152 * @param contextNode the context node for the sibling iterator.
153 * @return A possibly-empty iterator (not null).
154 */
155 public Iterator getFollowingSiblingAxisIterator(Object contextNode) {
156 return new NodeIterator((Node) contextNode) {
157 protected Node getFirstNode(Node node) {
158 return getNextNode(node);
159 }
160
161 protected Node getNextNode(Node node) {
162 return getNextSibling(node);
163 }
164 };
165 }
166
167 /***
168 * Get an iterator over all preceding siblings.
169 *
170 * @param contextNode The context node for the preceding sibling axis.
171 * @return A possibly-empty iterator (not null).
172 */
173 public Iterator getPrecedingSiblingAxisIterator(Object contextNode) {
174 return new NodeIterator((Node) contextNode) {
175 protected Node getFirstNode(Node node) {
176 return getNextNode(node);
177 }
178
179 protected Node getNextNode(Node node) {
180 return getPreviousSibling(node);
181 }
182 };
183 }
184
185 /***
186 * Get an iterator over all following nodes, depth-first.
187 *
188 * @param contextNode The context node for the following axis.
189 * @return A possibly-empty iterator (not null).
190 */
191 public Iterator getFollowingAxisIterator(Object contextNode) {
192 return new NodeIterator((Node) contextNode) {
193 protected Node getFirstNode(Node node) {
194 if (node == null)
195 return null;
196 else {
197 Node sibling = getNextSibling(node);
198 if (sibling == null)
199 return getFirstNode(node.jjtGetParent());
200 else
201 return sibling;
202 }
203 }
204
205 protected Node getNextNode(Node node) {
206 if (node == null)
207 return null;
208 else {
209 Node n = getFirstChild(node);
210 if (n == null)
211 n = getNextSibling(node);
212 if (n == null)
213 return getFirstNode(node.jjtGetParent());
214 else
215 return n;
216 }
217 }
218 };
219 }
220
221 /***
222 * Get an iterator over all preceding nodes, depth-first.
223 *
224 * @param contextNode The context node for the preceding axis.
225 * @return A possibly-empty iterator (not null).
226 */
227 public Iterator getPrecedingAxisIterator(Object contextNode) {
228 return new NodeIterator((Node) contextNode) {
229 protected Node getFirstNode(Node node) {
230 if (node == null)
231 return null;
232 else {
233 Node sibling = getPreviousSibling(node);
234 if (sibling == null)
235 return getFirstNode(node.jjtGetParent());
236 else
237 return sibling;
238 }
239 }
240
241 protected Node getNextNode(Node node) {
242 if (node == null)
243 return null;
244 else {
245 Node n = getLastChild(node);
246 if (n == null)
247 n = getPreviousSibling(node);
248 if (n == null)
249 return getFirstNode(node.jjtGetParent());
250 else
251 return n;
252 }
253 }
254 };
255 }
256
257 public Object getDocumentNode(Object contextNode) {
258 if (isDocument(contextNode)) {
259 return contextNode;
260 }
261 return getDocumentNode(getParentNode(contextNode));
262 }
263 }