001 /**
002 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
003 */
004 package net.sourceforge.pmd.lang.ast.xpath;
005
006 import java.util.ArrayList;
007 import java.util.Iterator;
008
009 import net.sourceforge.pmd.lang.ast.Node;
010 import net.sourceforge.pmd.lang.ast.RootNode;
011
012 import org.jaxen.DefaultNavigator;
013 import org.jaxen.XPath;
014 import org.jaxen.util.SingleObjectIterator;
015
016 /**
017 * @author daniels
018 */
019 public class DocumentNavigator extends DefaultNavigator {
020
021 private final static Iterator<Node> EMPTY_ITERATOR = new ArrayList<Node>().iterator();
022
023 public String getAttributeName(Object arg0) {
024 return ((Attribute) arg0).getName();
025 }
026
027 public String getAttributeNamespaceUri(Object arg0) {
028 return "";
029 }
030
031 public String getAttributeQName(Object arg0) {
032 return ((Attribute) arg0).getName();
033 }
034
035 public String getAttributeStringValue(Object arg0) {
036 return ((Attribute) arg0).getStringValue();
037 }
038
039 public String getCommentStringValue(Object arg0) {
040 return "";
041 }
042
043 public String getElementName(Object node) {
044 return node.toString();
045 }
046
047 public String getElementNamespaceUri(Object arg0) {
048 return "";
049 }
050
051 public String getElementQName(Object arg0) {
052 return getElementName(arg0);
053 }
054
055 public String getElementStringValue(Object arg0) {
056 return "";
057 }
058
059 public String getNamespacePrefix(Object arg0) {
060 return "";
061 }
062
063 public String getNamespaceStringValue(Object arg0) {
064 return "";
065 }
066
067 public String getTextStringValue(Object arg0) {
068 return "";
069 }
070
071 public boolean isAttribute(Object arg0) {
072 return arg0 instanceof Attribute;
073 }
074
075 public boolean isComment(Object arg0) {
076 return false;
077 }
078
079 public boolean isDocument(Object arg0) {
080 return arg0 instanceof RootNode;
081 }
082
083 public boolean isElement(Object arg0) {
084 return arg0 instanceof Node;
085 }
086
087 public boolean isNamespace(Object arg0) {
088 return false;
089 }
090
091 public boolean isProcessingInstruction(Object arg0) {
092 return false;
093 }
094
095 public boolean isText(Object arg0) {
096 return false;
097 }
098
099 public XPath parseXPath(String arg0) {
100 return null;
101 }
102
103 @Override
104 public Object getParentNode(Object arg0) {
105 if (arg0 instanceof Node) {
106 return ((Node) arg0).jjtGetParent();
107 }
108 return ((Attribute) arg0).getParent();
109 }
110
111 @Override
112 public Iterator<Attribute> getAttributeAxisIterator(Object arg0) {
113 if (arg0 instanceof AttributeNode) {
114 return ((AttributeNode) arg0).getAttributeIterator();
115 } else {
116 return new AttributeAxisIterator((Node) arg0);
117 }
118 }
119
120 /**
121 * Get an iterator over all of this node's children.
122 *
123 * @param contextNode The context node for the child axis.
124 * @return A possibly-empty iterator (not null).
125 */
126 @Override
127 public Iterator<Node> getChildAxisIterator(Object contextNode) {
128 return new NodeIterator((Node) contextNode) {
129 @Override
130 protected Node getFirstNode(Node node) {
131 return getFirstChild(node);
132 }
133
134 @Override
135 protected Node getNextNode(Node node) {
136 return getNextSibling(node);
137 }
138 };
139 }
140
141 /**
142 * Get a (single-member) iterator over this node's parent.
143 *
144 * @param contextNode the context node for the parent axis.
145 * @return A possibly-empty iterator (not null).
146 */
147 @Override
148 public Iterator<Node> getParentAxisIterator(Object contextNode) {
149 if (isAttribute(contextNode)) {
150 return new SingleObjectIterator(((Attribute) contextNode).getParent());
151 }
152 Node parent = ((Node) contextNode).jjtGetParent();
153 if (parent != null) {
154 return new SingleObjectIterator(parent);
155 } else {
156 return EMPTY_ITERATOR;
157 }
158 }
159
160 /**
161 * Get an iterator over all following siblings.
162 *
163 * @param contextNode the context node for the sibling iterator.
164 * @return A possibly-empty iterator (not null).
165 */
166 @Override
167 public Iterator<Node> getFollowingSiblingAxisIterator(Object contextNode) {
168 return new NodeIterator((Node) contextNode) {
169 @Override
170 protected Node getFirstNode(Node node) {
171 return getNextNode(node);
172 }
173
174 @Override
175 protected Node getNextNode(Node node) {
176 return getNextSibling(node);
177 }
178 };
179 }
180
181 /**
182 * Get an iterator over all preceding siblings.
183 *
184 * @param contextNode The context node for the preceding sibling axis.
185 * @return A possibly-empty iterator (not null).
186 */
187 @Override
188 public Iterator<Node> getPrecedingSiblingAxisIterator(Object contextNode) {
189 return new NodeIterator((Node) contextNode) {
190 @Override
191 protected Node getFirstNode(Node node) {
192 return getNextNode(node);
193 }
194
195 @Override
196 protected Node getNextNode(Node node) {
197 return getPreviousSibling(node);
198 }
199 };
200 }
201
202 /**
203 * Get an iterator over all following nodes, depth-first.
204 *
205 * @param contextNode The context node for the following axis.
206 * @return A possibly-empty iterator (not null).
207 */
208 @Override
209 public Iterator<Node> getFollowingAxisIterator(Object contextNode) {
210 return new NodeIterator((Node) contextNode) {
211 @Override
212 protected Node getFirstNode(Node node) {
213 if (node == null) {
214 return null;
215 } else {
216 Node sibling = getNextSibling(node);
217 if (sibling == null) {
218 return getFirstNode(node.jjtGetParent());
219 } else {
220 return sibling;
221 }
222 }
223 }
224
225 @Override
226 protected Node getNextNode(Node node) {
227 if (node == null) {
228 return null;
229 } else {
230 Node n = getFirstChild(node);
231 if (n == null) {
232 n = getNextSibling(node);
233 }
234 if (n == null) {
235 return getFirstNode(node.jjtGetParent());
236 } else {
237 return n;
238 }
239 }
240 }
241 };
242 }
243
244 /**
245 * Get an iterator over all preceding nodes, depth-first.
246 *
247 * @param contextNode The context node for the preceding axis.
248 * @return A possibly-empty iterator (not null).
249 */
250 @Override
251 public Iterator<Node> getPrecedingAxisIterator(Object contextNode) {
252 return new NodeIterator((Node) contextNode) {
253 @Override
254 protected Node getFirstNode(Node node) {
255 if (node == null) {
256 return null;
257 } else {
258 Node sibling = getPreviousSibling(node);
259 if (sibling == null) {
260 return getFirstNode(node.jjtGetParent());
261 } else {
262 return sibling;
263 }
264 }
265 }
266
267 @Override
268 protected Node getNextNode(Node node) {
269 if (node == null) {
270 return null;
271 } else {
272 Node n = getLastChild(node);
273 if (n == null) {
274 n = getPreviousSibling(node);
275 }
276 if (n == null) {
277 return getFirstNode(node.jjtGetParent());
278 } else {
279 return n;
280 }
281 }
282 }
283 };
284 }
285
286 @Override
287 public Object getDocumentNode(Object contextNode) {
288 if (isDocument(contextNode)) {
289 return contextNode;
290 }
291 return getDocumentNode(getParentNode(contextNode));
292 }
293 }
|