Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/puppycrawl/tools/checkstyle/checks/xpath/DocumentNavigator.java


1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2003  Oliver Burn
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ////////////////////////////////////////////////////////////////////////////////
19  package com.puppycrawl.tools.checkstyle.checks.xpath;
20  
21  import java.util.ArrayList;
22  import java.util.Iterator;
23  
24  import org.jaxen.DefaultNavigator;
25  import org.jaxen.XPath;
26  import org.jaxen.util.SingleObjectIterator;
27  import org.saxpath.SAXPathException;
28  
29  import com.puppycrawl.tools.checkstyle.api.DetailAST;
30  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
31  
32  /**
33   * Navigates around a DetailAST, using XPath semantics.
34   * Requires jaxen, http://jaxen.sourceforge.net and
35   * saxpath, http://sourceforge.net/projects/saxpath/.
36   * Idea shamelessly stolen from the equivalent PMD code (pmd.sourceforge.net).
37   * @author Rick Giles
38   */
39  public class DocumentNavigator
40      extends DefaultNavigator
41  {
42      /** Iterator for an empty sequence */
43      private static final Iterator EMPTY_ITERATOR = new ArrayList().iterator();
44  
45      /**
46       * @see org.jaxen.DefaultNavigator#getAttributeName(java.lang.Object)
47       */
48      public String getAttributeName(Object aObject)
49      {
50          return ((Attribute) aObject).getName();
51      }
52  
53      /**
54       * @see org.jaxen.DefaultNavigator#getAttributeNamespaceUri
55       */
56      public String getAttributeNamespaceUri(Object aObject)
57      {
58          return null;
59      }
60  
61      /**
62       * @see org.jaxen.DefaultNavigator#getAttributeQName(java.lang.Object)
63       */
64      public String getAttributeQName(Object aObject)
65      {
66          return ((Attribute) aObject).getName();
67      }
68  
69      /**
70       * @see org.jaxen.DefaultNavigator#getAttributeStringValue(java.lang.Object)
71       */
72      public String getAttributeStringValue(Object aObject)
73      {
74          return ((Attribute) aObject).getValue();
75      }
76  
77      /**
78       * @see org.jaxen.DefaultNavigator#getCommentStringValue(java.lang.Object)
79       */
80      public String getCommentStringValue(Object aObject)
81      {
82          return null;
83      }
84  
85      /**
86       * @see org.jaxen.DefaultNavigator#getElementName(java.lang.Object)
87       */
88      public String getElementName(Object aObject)
89      {
90          final int type = ((DetailAST) aObject).getType();
91          return TokenTypes.getTokenName(type);
92      }
93  
94      /**
95       * @see org.jaxen.DefaultNavigator#getElementNamespaceUri(java.lang.Object)
96       */
97      public String getElementNamespaceUri(Object aObject)
98      {
99          return null;
100     }
101 
102     /**
103      * @see org.jaxen.DefaultNavigator#getElementQName(java.lang.Object)
104      */
105     public String getElementQName(Object aObject)
106     {
107         return getElementName(aObject);
108     }
109 
110     /**
111      * @see org.jaxen.DefaultNavigator#getElementStringValue(java.lang.Object)
112      */
113     public String getElementStringValue(Object aObject)
114     {
115         return null;
116     }
117 
118     /**
119      * @see org.jaxen.DefaultNavigator#getNamespacePrefix(java.lang.Object)
120      */
121     public String getNamespacePrefix(Object aObject)
122     {
123         return null;
124     }
125 
126     /**
127      * @see org.jaxen.DefaultNavigator#getNamespaceStringValue(java.lang.Object)
128      */
129     public String getNamespaceStringValue(Object aObject)
130     {
131         return null;
132     }
133 
134     /**
135      * @see org.jaxen.DefaultNavigator#getTextStringValue(java.lang.Object)
136      */
137     public String getTextStringValue(Object aObject)
138     {
139         return null;
140     }
141 
142     /**
143      * @see org.jaxen.DefaultNavigator#isAttribute(java.lang.Object)
144      */
145     public boolean isAttribute(Object aObject)
146     {
147         return aObject instanceof Attribute;
148     }
149 
150     /**
151      * @see org.jaxen.DefaultNavigator#isComment(java.lang.Object)
152      */
153     public boolean isComment(Object aObject)
154     {
155         return false;
156     }
157 
158     /**
159      * @see org.jaxen.DefaultNavigator#isDocument(java.lang.Object)
160      */
161     public boolean isDocument(Object aObject)
162     {
163         if (aObject instanceof DetailAST) {
164             final DetailAST node = (DetailAST) aObject;
165             return (node.getType() == TokenTypes.EOF);
166         }
167         else {
168             return false;
169         }
170     }
171 
172     /**
173      * @see org.jaxen.DefaultNavigator#isElement(java.lang.Object)
174      */
175     public boolean isElement(Object aObject)
176     {
177         return aObject instanceof DetailAST;
178     }
179 
180     /**
181      * @see org.jaxen.DefaultNavigator#isNamespace(java.lang.Object)
182      */
183     public boolean isNamespace(Object aObject)
184     {
185         return false;
186     }
187 
188     /**
189      * @see org.jaxen.DefaultNavigator#isProcessingInstruction(java.lang.Object)
190      */
191     public boolean isProcessingInstruction(Object aObject)
192     {
193         return false;
194     }
195 
196     /**
197      * @see org.jaxen.DefaultNavigator#isText(java.lang.Object)
198      */
199     public boolean isText(Object aObject)
200     {
201         return false;
202     }
203 
204     /**
205      * @see org.jaxen.DefaultNavigator#parseXPath(java.lang.String)
206      */
207     public XPath parseXPath(String aObject)
208         throws SAXPathException
209     {
210         return null;
211     }
212 
213     /**
214      * @see org.jaxen.Navigator#getParentNode(java.lang.Object)
215      */
216     public Object getParentNode(Object aObject)
217     {
218         if (aObject instanceof DetailAST) {
219             return ((DetailAST) aObject).getParent();
220         }
221         else {
222             return ((Attribute) aObject).getParent();
223         }
224     }
225 
226     /**
227      * @see org.jaxen.Navigator#getAttributeAxisIterator(java.lang.Object)
228      */
229     public Iterator getAttributeAxisIterator(Object aObject)
230     {
231         final DetailAST contextNode = (DetailAST) aObject;
232         return new AttributeAxisIterator(contextNode);
233     }
234 
235     /**
236      * Get an iterator over all of this node's children.
237      *
238      * @param aObject The context node for the child axis.
239      * @return A possibly-empty iterator (not null).
240      */
241     public Iterator getChildAxisIterator(Object aObject)
242     {
243         return new NodeIterator((DetailAST) aObject)
244         {
245             /** @see NodeIterator */
246             protected DetailAST getFirstNode(DetailAST aAST)
247             {
248                 return getFirstChild(aAST);
249             }
250 
251             /** @see NodeIterator */
252             protected DetailAST getNextNode(DetailAST aAST)
253             {
254                 return getNextSibling(aAST);
255             }
256         };
257     }
258 
259     /**
260      * Get a (single-member) iterator over this node's parent.
261      *
262      * @param aObject the context node for the parent axis.
263      * @return A possibly-empty iterator (not null).
264      */
265     public Iterator getParentAxisIterator(Object aObject)
266     {
267         if (isAttribute(aObject)) {
268             return new SingleObjectIterator(((Attribute) aObject).getParent());
269         }
270         else {
271             DetailAST parent = ((DetailAST) aObject).getParent();
272             if (parent != null) {
273                 return new SingleObjectIterator(parent);
274             }
275             else {
276                 return EMPTY_ITERATOR;
277             }
278         }
279     }
280 
281     /**
282      * Get an iterator over all following siblings.
283      *
284      * @param aObject the context node for the sibling iterator.
285      * @return A possibly-empty iterator (not null).
286      */
287     public Iterator getFollowingSiblingAxisIterator(Object aObject)
288     {
289         return new NodeIterator((DetailAST) aObject)
290         {
291             /** @see NodeIterator */
292             protected DetailAST getFirstNode(DetailAST aAST)
293             {
294                 return getNextNode(aAST);
295             }
296 
297             /** @see NodeIterator */
298             protected DetailAST getNextNode(DetailAST aAST)
299             {
300                 return getNextSibling(aAST);
301             }
302         };
303     }
304 
305     /**
306      * Get an iterator over all preceding siblings.
307      *
308      * @param aObject The context node for the preceding sibling axis.
309      * @return A possibly-empty iterator (not null).
310      */
311     public Iterator getPrecedingSiblingAxisIterator(Object aObject)
312     {
313         return new NodeIterator((DetailAST) aObject)
314         {
315             /** @see NodeIterator */
316             protected DetailAST getFirstNode(DetailAST aAST)
317             {
318                 return getNextNode(aAST);
319             }
320 
321             /** @see NodeIterator */
322             protected DetailAST getNextNode(DetailAST aAST)
323             {
324                 return getPreviousSibling(aAST);
325             }
326         };
327     }
328 
329     /**
330      * Get an iterator over all following nodes, depth-first.
331      *
332      * @param aObject The context node for the following axis.
333      * @return A possibly-empty iterator (not null).
334      */
335     public Iterator getFollowingAxisIterator(Object aObject)
336     {
337         return new NodeIterator((DetailAST) aObject)
338         {
339             /** @see NodeIterator */
340             protected DetailAST getFirstNode(DetailAST aAST)
341             {
342                 if (aAST == null) {
343                     return null;
344                 }
345                 else {
346                     final DetailAST sibling = getNextSibling(aAST);
347                     if (sibling == null) {
348                         return getFirstNode(aAST.getParent());
349                     }
350                     else {
351                         return sibling;
352                     }
353                 }
354             }
355 
356             /** @see NodeIterator */
357             protected DetailAST getNextNode(DetailAST aAST)
358             {
359                 if (aAST == null) {
360                     return null;
361                 }
362                 else {
363                     DetailAST n = getFirstChild(aAST);
364                     if (n == null) {
365                         n = getNextSibling(aAST);
366                     }
367                     if (n == null) {
368                         return getFirstNode(aAST.getParent());
369                     }
370                     else {
371                         return n;
372                     }
373                 }
374             }
375         };
376     }
377 
378     /**
379      * Get an iterator over all preceding nodes, depth-first.
380      *
381      * @param aObject The context node for the preceding axis.
382      * @return A possibly-empty iterator (not null).
383      */
384     public Iterator getPrecedingAxisIterator(Object aObject)
385     {
386         return new NodeIterator((DetailAST) aObject)
387         {
388             /** @see NodeIterator */
389             protected DetailAST getFirstNode(DetailAST aAST)
390             {
391                 if (aAST == null) {
392                     return null;
393                 }
394                 else {
395                     final DetailAST sibling = getPreviousSibling(aAST);
396                     if (sibling == null) {
397                         return getFirstNode(aAST.getParent());
398                     }
399                     else {
400                         return sibling;
401                     }
402                 }
403             }
404 
405             /** @see NodeIterator */
406             protected DetailAST getNextNode(DetailAST aAST)
407             {
408                 if (aAST == null) {
409                     return null;
410                 }
411                 else {
412                     DetailAST n = getLastChild(aAST);
413                     if (n == null) {
414                         n = getPreviousSibling(aAST);
415                     }
416                     if (n == null) {
417                         return getFirstNode(aAST.getParent());
418                     }
419                     else {
420                         return n;
421                     }
422                 }
423             }
424         };
425     }
426 
427     /** @see org.jaxen.Navigator#getDocumentNode(java.lang.Object) */
428     public Object getDocumentNode(Object aObject)
429     {
430         if (isDocument(aObject)) {
431             return aObject;
432         }
433         else {
434             return getDocumentNode(getParentNode(aObject));
435         }
436     }
437 }