001: /* Generated By:JJTree: Do not edit this line. SimpleNode.java */
002: package net.sourceforge.pmd.ast;
003:
004: import net.sourceforge.pmd.dfa.IDataFlowNode;
005: import net.sourceforge.pmd.jaxen.Attribute;
006: import net.sourceforge.pmd.jaxen.DocumentNavigator;
007: import net.sourceforge.pmd.symboltable.Scope;
008: import org.jaxen.BaseXPath;
009: import org.jaxen.JaxenException;
010: import org.w3c.dom.Document;
011: import org.w3c.dom.Element;
012:
013: import javax.xml.parsers.DocumentBuilderFactory;
014: import javax.xml.parsers.DocumentBuilder;
015: import javax.xml.parsers.ParserConfigurationException;
016: import java.util.ArrayList;
017: import java.util.Iterator;
018: import java.util.List;
019:
020: public abstract class SimpleNode implements Node {
021:
022: protected Node parent;
023: protected Node[] children;
024: protected int id;
025: protected JavaParser parser;
026: private String image;
027: protected int beginLine = -1;
028: protected int endLine;
029: protected int beginColumn = -1;
030: protected int endColumn;
031: private Scope scope;
032: private IDataFlowNode dataFlowNode;
033:
034: public IDataFlowNode getDataFlowNode() {
035: if (this .dataFlowNode == null) {
036: if (this .parent != null) {
037: return ((SimpleNode) parent).getDataFlowNode();
038: }
039: return null; //TODO wise?
040: }
041: return dataFlowNode;
042: }
043:
044: public void setDataFlowNode(IDataFlowNode dataFlowNode) {
045: this .dataFlowNode = dataFlowNode;
046: }
047:
048: public SimpleNode(int i) {
049: id = i;
050: }
051:
052: public SimpleNode(JavaParser p, int i) {
053: this (i);
054: parser = p;
055: }
056:
057: public void setScope(Scope scope) {
058: this .scope = scope;
059: }
060:
061: public Scope getScope() {
062: if (scope == null) {
063: return ((SimpleNode) parent).getScope();
064: }
065: return scope;
066: }
067:
068: public int getBeginLine() {
069: return beginLine;
070: }
071:
072: // A label is a more visually useful image, e.g.
073: // int[[ for a primary suffix that's a 2D array of ints
074: // this is used only by the Designer to show nodes more helpfully
075: public String getLabel() {
076: return null;
077: }
078:
079: public boolean hasImageEqualTo(String arg) {
080: return image != null && image.equals(arg);
081: }
082:
083: public void testingOnly__setBeginLine(int i) {
084: this .beginLine = i;
085: }
086:
087: public void testingOnly__setBeginColumn(int i) {
088: this .beginColumn = i;
089: }
090:
091: public int getBeginColumn() {
092: if (beginColumn != -1) {
093: return beginColumn;
094: } else {
095: if ((children != null) && (children.length > 0)) {
096: return ((SimpleNode) children[0]).getBeginColumn();
097: } else {
098: throw new RuntimeException(
099: "Unable to determine begining line of Node.");
100: }
101: }
102: }
103:
104: public String getImage() {
105: return image;
106: }
107:
108: public void setImage(String image) {
109: this .image = image;
110: }
111:
112: public int getEndLine() {
113: return endLine;
114: }
115:
116: public int getEndColumn() {
117: return endColumn;
118: }
119:
120: public Node getNthParent(int n) {
121: Node result = null;
122: for (int i = 0; i < n; i++) {
123: if (result == null) {
124: result = this .jjtGetParent();
125: } else {
126: result = result.jjtGetParent();
127: }
128: }
129: return result;
130: }
131:
132: /**
133: * Traverses up the tree to find the first parent instance of type parentType
134: *
135: * @param parentType class which you want to find.
136: * @return Node of type parentType. Returns null if none found.
137: */
138: public <T> T getFirstParentOfType(Class<T> parentType) {
139: Node parentNode = jjtGetParent();
140: while (parentNode != null
141: && parentNode.getClass() != parentType) {
142: parentNode = parentNode.jjtGetParent();
143: }
144: return (T) parentNode;
145: }
146:
147: /**
148: * Traverses up the tree to find all of the parent instances of type parentType
149: *
150: * @param parentType classes which you want to find.
151: * @return List of parentType instances found.
152: */
153: public <T> List<T> getParentsOfType(Class<T> parentType) {
154: List<T> parents = new ArrayList<T>();
155: Node parentNode = jjtGetParent();
156: while (parentNode != null) {
157: if (parentNode.getClass() == parentType) {
158: parents.add((T) parentNode);
159: }
160: parentNode = parentNode.jjtGetParent();
161: }
162: return parents;
163: }
164:
165: public <T> List<T> findChildrenOfType(Class<T> targetType) {
166: List<T> list = new ArrayList<T>();
167: findChildrenOfType(targetType, list);
168: return list;
169: }
170:
171: public <T> void findChildrenOfType(Class<T> targetType,
172: List<T> results) {
173: findChildrenOfType(this , targetType, results, true);
174: }
175:
176: public <T> void findChildrenOfType(Class<T> targetType,
177: List<T> results, boolean descendIntoNestedClasses) {
178: this .findChildrenOfType(this , targetType, results,
179: descendIntoNestedClasses);
180: }
181:
182: private <T> void findChildrenOfType(Node node, Class<T> targetType,
183: List<T> results, boolean descendIntoNestedClasses) {
184: if (node.getClass().equals(targetType)) {
185: results.add((T) node);
186: }
187:
188: if (!descendIntoNestedClasses) {
189: if (node instanceof ASTClassOrInterfaceDeclaration
190: && ((ASTClassOrInterfaceDeclaration) node)
191: .isNested()) {
192: return;
193: }
194:
195: if (node instanceof ASTClassOrInterfaceBodyDeclaration
196: && ((ASTClassOrInterfaceBodyDeclaration) node)
197: .isAnonymousInnerClass()) {
198: return;
199: }
200: }
201:
202: for (int i = 0; i < node.jjtGetNumChildren(); i++) {
203: Node child = node.jjtGetChild(i);
204: if (child.jjtGetNumChildren() > 0) {
205: findChildrenOfType(child, targetType, results,
206: descendIntoNestedClasses);
207: } else {
208: if (child.getClass().equals(targetType)) {
209: results.add((T) child);
210: }
211: }
212: }
213: }
214:
215: public void jjtSetParent(Node n) {
216: parent = n;
217: }
218:
219: public Node jjtGetParent() {
220: return parent;
221: }
222:
223: public void jjtAddChild(Node n, int i) {
224: if (children == null) {
225: children = new Node[i + 1];
226: } else if (i >= children.length) {
227: Node c[] = new Node[i + 1];
228: System.arraycopy(children, 0, c, 0, children.length);
229: children = c;
230: }
231: children[i] = n;
232: }
233:
234: public Node jjtGetChild(int i) {
235: return children[i];
236: }
237:
238: public int jjtGetNumChildren() {
239: return (children == null) ? 0 : children.length;
240: }
241:
242: public String toString(String prefix) {
243: return prefix + toString();
244: }
245:
246: public Document asXml() {
247: try {
248: DocumentBuilderFactory dbf = DocumentBuilderFactory
249: .newInstance();
250: DocumentBuilder db = dbf.newDocumentBuilder();
251: Document document = db.newDocument();
252: appendElement(document);
253: return document;
254: } catch (ParserConfigurationException pce) {
255: throw new RuntimeException(pce);
256: }
257: }
258:
259: protected void appendElement(org.w3c.dom.Node parentNode) {
260: DocumentNavigator docNav = new DocumentNavigator();
261: Document ownerDocument = parentNode.getOwnerDocument();
262: if (ownerDocument == null) {
263: //If the parentNode is a Document itself, it's ownerDocument is null
264: ownerDocument = (Document) parentNode;
265: }
266: String elementName = docNav.getElementName(this );
267: Element element = ownerDocument.createElement(elementName);
268: parentNode.appendChild(element);
269: for (Iterator<Attribute> iter = docNav
270: .getAttributeAxisIterator(this ); iter.hasNext();) {
271: Attribute attr = iter.next();
272: element.setAttribute(attr.getName(), attr.getValue());
273: }
274: for (Iterator iter = docNav.getChildAxisIterator(this ); iter
275: .hasNext();) {
276: SimpleNode child = (SimpleNode) iter.next();
277: child.appendElement(element);
278: }
279: }
280:
281: /* Override this method if you want to customize how the node dumps
282: out its children. */
283: public void dump(String prefix) {
284: System.out.println(toString(prefix)
285: + (image == null ? "" : ":" + image));
286: dumpChildren(prefix);
287: }
288:
289: protected void dumpChildren(String prefix) {
290: if (children != null) {
291: for (int i = 0; i < children.length; ++i) {
292: SimpleNode n = (SimpleNode) children[i];
293: if (n != null) {
294: n.dump(prefix + " ");
295: }
296: }
297: }
298: }
299:
300: /**
301: * Traverses down the tree to find the first child instance of type childType
302: *
303: * @param childType class which you want to find.
304: * @return Node of type childType. Returns <code>null</code> if none found.
305: */
306: public <T> T getFirstChildOfType(Class<T> childType) {
307: return getFirstChildOfType(childType, this );
308: }
309:
310: private <T> T getFirstChildOfType(Class<T> childType, Node node) {
311: for (int i = 0; i < node.jjtGetNumChildren(); i++) {
312: Node n = node.jjtGetChild(i);
313: if (n != null) {
314: if (n.getClass().equals(childType))
315: return (T) n;
316: T n2 = getFirstChildOfType(childType, n);
317: if (n2 != null)
318: return n2;
319: }
320: }
321: return null;
322: }
323:
324: /**
325: * Finds if this node contains a child of the given type.
326: * This is an utility method that uses {@link #findChildrenOfType(Class)}
327: *
328: * @param type the node type to search
329: * @return <code>true</code> if there is at lease on child of the given type and <code>false</code> in any other case
330: */
331: public final <T> boolean containsChildOfType(Class<T> type) {
332: return !findChildrenOfType(type).isEmpty();
333: }
334:
335: public List findChildNodesWithXPath(String xpathString)
336: throws JaxenException {
337: return new BaseXPath(xpathString, new DocumentNavigator())
338: .selectNodes(this);
339: }
340: }
|