1 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; } 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 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 137 public Node getFirstParentOfType(Class parentType) { 138 Node parentNode = jjtGetParent(); 139 while (parentNode != null && parentNode.getClass() != parentType) { 140 parentNode = parentNode.jjtGetParent(); 141 } 142 return parentNode; 143 } 144 145 151 public List getParentsOfType(Class parentType) { 152 List parents = new ArrayList (); 153 Node parentNode = jjtGetParent(); 154 while (parentNode != null) { 155 if (parentNode.getClass() == parentType) { 156 parents.add(parentNode); 157 } 158 parentNode = parentNode.jjtGetParent(); 159 } 160 return parents; 161 } 162 163 public List findChildrenOfType(Class targetType) { 164 List list = new ArrayList (); 165 findChildrenOfType(targetType, list); 166 return list; 167 } 168 169 public void findChildrenOfType(Class targetType, List results) { 170 findChildrenOfType(this, targetType, results, true); 171 } 172 173 public void findChildrenOfType(Class targetType, List results, boolean descendIntoNestedClasses) { 174 this.findChildrenOfType(this, targetType, results, descendIntoNestedClasses); 175 } 176 177 private void findChildrenOfType(Node node, Class targetType, List results, boolean descendIntoNestedClasses) { 178 if (node.getClass().equals(targetType)) { 179 results.add(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(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 ownerDocument = (Document ) parentNode; 253 } 254 String elementName = docNav.getElementName(this); 255 Element element = ownerDocument.createElement(elementName); 256 parentNode.appendChild(element); 257 for (Iterator iter = docNav.getAttributeAxisIterator(this); iter.hasNext();) { 258 Attribute attr = (Attribute) 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 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 292 public Node getFirstChildOfType(Class childType) { 293 return getFirstChildOfType(childType, this); 294 } 295 296 private Node getFirstChildOfType(Class 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 n; 302 Node n2 = getFirstChildOfType(childType, n); 303 if (n2 != null) 304 return n2; 305 } 306 } 307 return null; 308 } 309 310 317 public final boolean containsChildOfType(Class 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 } 325 | Popular Tags |