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 }