View Javadoc

1   /* Generated By:JJTree: Do not edit this line. SimpleNode.java */
2   package net.sourceforge.pmd.ast;
3   
4   import net.sourceforge.pmd.dfa.IDataFlowNode;
5   import net.sourceforge.pmd.jaxen.Attribute;
6   import net.sourceforge.pmd.jaxen.DocumentNavigator;
7   import net.sourceforge.pmd.symboltable.Scope;
8   import org.jaxen.BaseXPath;
9   import org.jaxen.JaxenException;
10  import org.w3c.dom.Document;
11  import org.w3c.dom.Element;
12  
13  import javax.xml.parsers.DocumentBuilderFactory;
14  import javax.xml.parsers.DocumentBuilder;
15  import javax.xml.parsers.ParserConfigurationException;
16  import java.util.ArrayList;
17  import java.util.Iterator;
18  import java.util.List;
19  
20  public abstract class SimpleNode implements Node {
21  
22      protected Node parent;
23      protected Node[] children;
24      protected int id;
25      protected JavaParser parser;
26      private String image;
27      protected int beginLine = -1;
28      protected int endLine;
29      protected int beginColumn = -1;
30      protected int endColumn;
31      private Scope scope;
32      private IDataFlowNode dataFlowNode;
33  
34      public IDataFlowNode getDataFlowNode() {
35          if (this.dataFlowNode == null) {
36              if (this.parent != null) {
37                  return ((SimpleNode) parent).getDataFlowNode();
38              }
39              return null; //TODO wise?
40          }
41          return dataFlowNode;
42      }
43  
44      public void setDataFlowNode(IDataFlowNode dataFlowNode) {
45          this.dataFlowNode = dataFlowNode;
46      }
47  
48      public SimpleNode(int i) {
49          id = i;
50      }
51  
52      public SimpleNode(JavaParser p, int i) {
53          this(i);
54          parser = p;
55      }
56  
57      public void setScope(Scope scope) {
58          this.scope = scope;
59      }
60  
61      public Scope getScope() {
62          if (scope == null) {
63              return ((SimpleNode) parent).getScope();
64          }
65          return scope;
66      }
67  
68      public int getBeginLine() {
69          return beginLine;
70      }
71  
72      // A label is a more visually useful image, e.g.
73      // int[[ for a primary suffix that's a 2D array of ints
74      // this is used only by the Designer to show nodes more helpfully
75      public String getLabel() {
76          return null;        
77      }
78  
79      public boolean hasImageEqualTo(String arg) {
80      	return image != null && image.equals(arg);
81      }
82      
83      public void testingOnly__setBeginLine(int i) {
84          this.beginLine = i;
85      }
86  
87      public void testingOnly__setBeginColumn(int i) {
88          this.beginColumn = i;
89      }
90  
91      public int getBeginColumn() {
92          if (beginColumn != -1) {
93              return beginColumn;
94          } else {
95              if ((children != null) && (children.length > 0)) {
96                  return ((SimpleNode) children[0]).getBeginColumn();
97              } else {
98                  throw new RuntimeException("Unable to determine begining line of Node.");
99              }
100         }
101     }
102 
103     public String getImage() {
104         return image;
105     }
106 
107     public void setImage(String image) {
108         this.image = image;
109     }
110 
111     public int getEndLine() {
112         return endLine;
113     }
114 
115     public int getEndColumn() {
116         return endColumn;
117     }
118 
119     public Node getNthParent(int n) {
120         Node result = null;
121         for (int i = 0; i < n; i++) {
122             if (result == null) {
123                 result = this.jjtGetParent();
124             } else {
125                 result = result.jjtGetParent();
126             }
127         }
128         return result;
129     }
130 
131     /**
132      * Traverses up the tree to find the first parent instance of type parentType
133      *
134      * @param parentType class which you want to find.
135      * @return Node of type parentType.  Returns null if none found.
136      */
137     public <T> T getFirstParentOfType(Class<T> parentType) {
138         Node parentNode = jjtGetParent();
139         while (parentNode != null && parentNode.getClass() != parentType) {
140             parentNode = parentNode.jjtGetParent();
141         }
142         return (T) parentNode;
143     }
144 
145     /**
146      * Traverses up the tree to find all of the parent instances of type parentType
147      *
148      * @param parentType classes which you want to find.
149      * @return List of parentType instances found.
150      */
151     public <T> List<T> getParentsOfType(Class<T> parentType) {
152         List<T> parents = new ArrayList<T>();
153         Node parentNode = jjtGetParent();
154         while (parentNode != null) {
155             if (parentNode.getClass() == parentType) {
156                 parents.add((T) parentNode);
157             }
158             parentNode = parentNode.jjtGetParent();
159         }
160         return parents;
161     }
162 
163     public <T> List<T> findChildrenOfType(Class<T> targetType) {
164         List<T> list = new ArrayList<T>();
165         findChildrenOfType(targetType, list);
166         return list;
167     }
168 
169     public <T> void findChildrenOfType(Class<T> targetType, List<T> results) {
170         findChildrenOfType(this, targetType, results, true);
171     }
172 
173     public <T> void findChildrenOfType(Class<T> targetType, List<T> results, boolean descendIntoNestedClasses) {
174         this.findChildrenOfType(this, targetType, results, descendIntoNestedClasses);
175     }
176 
177     private <T> void findChildrenOfType(Node node, Class<T> targetType, List<T> results, boolean descendIntoNestedClasses) {
178         if (node.getClass().equals(targetType)) {
179             results.add((T) node);
180         }
181 
182         if (!descendIntoNestedClasses) {
183             if (node instanceof ASTClassOrInterfaceDeclaration && ((ASTClassOrInterfaceDeclaration) node).isNested()) {
184                 return;
185             }
186 
187             if (node instanceof ASTClassOrInterfaceBodyDeclaration && ((ASTClassOrInterfaceBodyDeclaration) node).isAnonymousInnerClass()) {
188                 return;
189             }
190         }
191 
192         for (int i = 0; i < node.jjtGetNumChildren(); i++) {
193             Node child = node.jjtGetChild(i);
194             if (child.jjtGetNumChildren() > 0) {
195                 findChildrenOfType(child, targetType, results, descendIntoNestedClasses);
196             } else {
197                 if (child.getClass().equals(targetType)) {
198                     results.add((T) child);
199                 }
200             }
201         }
202     }
203 
204     public void jjtSetParent(Node n) {
205         parent = n;
206     }
207 
208     public Node jjtGetParent() {
209         return parent;
210     }
211 
212     public void jjtAddChild(Node n, int i) {
213         if (children == null) {
214             children = new Node[i + 1];
215         } else if (i >= children.length) {
216             Node c[] = new Node[i + 1];
217             System.arraycopy(children, 0, c, 0, children.length);
218             children = c;
219         }
220         children[i] = n;
221     }
222 
223     public Node jjtGetChild(int i) {
224         return children[i];
225     }
226 
227     public int jjtGetNumChildren() {
228         return (children == null) ? 0 : children.length;
229     }
230 
231     public String toString(String prefix) {
232         return prefix + toString();
233     }
234 
235     public Document asXml() {
236         try {
237             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
238             DocumentBuilder db = dbf.newDocumentBuilder();
239             Document document = db.newDocument();
240             appendElement(document);
241             return document;
242         } catch (ParserConfigurationException pce) {
243             throw new RuntimeException(pce);
244         }
245     }
246 
247     protected void appendElement(org.w3c.dom.Node parentNode) {
248         DocumentNavigator docNav = new DocumentNavigator();
249         Document ownerDocument = parentNode.getOwnerDocument();
250         if (ownerDocument == null) {
251             //If the parentNode is a Document itself, it's ownerDocument is null
252             ownerDocument = (Document) parentNode;
253         }
254         String elementName = docNav.getElementName(this);
255         Element element = ownerDocument.createElement(elementName);
256         parentNode.appendChild(element);
257         for (Iterator<Attribute> iter = docNav.getAttributeAxisIterator(this); iter.hasNext();) {
258             Attribute attr = iter.next();
259             element.setAttribute(attr.getName(), attr.getValue());
260         }
261         for (Iterator iter = docNav.getChildAxisIterator(this); iter.hasNext();) {
262             SimpleNode child = (SimpleNode) iter.next();
263             child.appendElement(element);
264         }
265     }
266 
267     /* Override this method if you want to customize how the node dumps
268        out its children. */
269     public void dump(String prefix) {
270         System.out.println(toString(prefix) + (image == null ? "" : ":" + image));
271         dumpChildren(prefix);
272     }
273 
274     protected void dumpChildren(String prefix) {
275         if (children != null) {
276             for (int i = 0; i < children.length; ++i) {
277                 SimpleNode n = (SimpleNode) children[i];
278                 if (n != null) {
279                     n.dump(prefix + " ");
280                 }
281             }
282         }
283     }
284 
285 
286     /**
287      * Traverses down the tree to find the first child instance of type childType
288      *
289      * @param childType class which you want to find.
290      * @return Node of type childType.  Returns <code>null</code> if none found.
291      */
292     public <T> T getFirstChildOfType(Class<T> childType) {
293         return getFirstChildOfType(childType, this);
294     }
295 
296     private <T> T getFirstChildOfType(Class<T> childType, Node node) {
297         for (int i = 0; i < node.jjtGetNumChildren(); i++) {
298             Node n = node.jjtGetChild(i);
299             if (n != null) {
300                 if (n.getClass().equals(childType))
301                     return (T) n;
302                 T n2 = getFirstChildOfType(childType, n);
303                 if (n2 != null)
304                     return n2;
305             }
306         }
307         return null;
308     }
309 
310     /**
311      * Finds if this node contains a child of the given type.
312      * This is an utility method that uses {@link #findChildrenOfType(Class)}
313      *
314      * @param type the node type to search
315      * @return <code>true</code> if there is at lease on child of the given type and <code>false</code> in any other case
316      */
317     public final <T> boolean containsChildOfType(Class<T> type) {
318         return !findChildrenOfType(type).isEmpty();
319     }
320 
321     public List findChildNodesWithXPath(String xpathString) throws JaxenException {
322         return new BaseXPath(xpathString, new DocumentNavigator()).selectNodes(this);
323     }
324 }