DocumentNavigator.java
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 ((Attributearg0).getName();
025     }
026 
027     public String getAttributeNamespaceUri(Object arg0) {
028   return "";
029     }
030 
031     public String getAttributeQName(Object arg0) {
032   return ((Attributearg0).getName();
033     }
034 
035     public String getAttributeStringValue(Object arg0) {
036   return ((Attributearg0).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 ((Nodearg0).jjtGetParent();
107   }
108   return ((Attributearg0).getParent();
109     }
110 
111     @Override
112     public Iterator<Attribute> getAttributeAxisIterator(Object arg0) {
113   if (arg0 instanceof AttributeNode) {
114       return ((AttributeNodearg0).getAttributeIterator();
115   else {
116       return new AttributeAxisIterator((Nodearg0);
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((NodecontextNode) {
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(((AttributecontextNode).getParent());
151   }
152   Node parent = ((NodecontextNode).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((NodecontextNode) {
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((NodecontextNode) {
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((NodecontextNode) {
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((NodecontextNode) {
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 }