View Javadoc

1   /***
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3   */
4   package net.sourceforge.pmd.jaxen;
5   import net.sourceforge.pmd.ast.Node;
6   
7   import java.lang.reflect.InvocationTargetException;
8   import java.lang.reflect.Method;
9   import java.util.Iterator;
10  
11  
12  public class AttributeAxisIterator implements Iterator {
13  
14      private static final Object[] EMPTY_OBJ_ARRAY = new Object[0];
15      private Object currObj;
16      private Method[] methods;
17      private int position;
18      private Node node;
19      
20      public AttributeAxisIterator(Node contextNode) {
21          this.node = contextNode;
22          this.methods = contextNode.getClass().getMethods();
23          this.position = 0;
24          this.currObj = getNextAttribute();
25      }
26      
27      public Object next() {
28          if(currObj == null) {
29              throw new IndexOutOfBoundsException();
30          }
31          Object ret = currObj;
32          currObj = getNextAttribute();
33          return ret;
34      }
35      
36      public boolean hasNext() {
37          return currObj != null;
38      }
39      
40      public void remove() {
41          throw new UnsupportedOperationException();
42      }
43      
44      private Attribute getNextAttribute() {
45          while (position < methods.length) {
46              Method method = methods[position];
47              try {
48                  if (isAttribute(method)) {
49                      Class returnType = method.getReturnType();
50                      if (Boolean.TYPE == returnType
51                          || String.class == returnType
52                          || Integer.TYPE == returnType) {
53                          Attribute attribute = getAttribute(node, method);
54                          if (attribute != null) {
55                              return attribute;
56                          }
57                      }
58                  }
59              } catch (IllegalAccessException e) {
60                  e.printStackTrace();
61              } catch (InvocationTargetException e) {
62                  e.printStackTrace();
63              } finally {
64                  position++;
65              }
66          }
67          return null;
68      }
69  
70      protected Attribute getAttribute(Node node, Method method)
71          throws IllegalAccessException, InvocationTargetException {
72          String name = method.getName();
73          name = truncateMethodName(name);
74          Object value = method.invoke(node, EMPTY_OBJ_ARRAY);
75          if (value != null) {
76              if (value instanceof String) {
77                  return new Attribute(node, name, (String) value);
78              } else {
79                  return new Attribute(node, name, String.valueOf(value));
80              }
81          } else {
82              return null;
83          }
84      }
85  
86      protected String truncateMethodName(String name) {
87          if (name.startsWith("is")) {
88              name = name.substring("is".length());
89          } else if (name.startsWith("uses")) {
90              name = name.substring("uses".length());
91          } else if (name.startsWith("has")) {
92              name = name.substring("has".length());
93          } else if (name.startsWith("get")) {
94              name = name.substring("get".length());
95          }
96          return name;
97      }
98  
99      protected boolean isAttribute(Method method) {
100         String name = method.getName();
101         Class returnType = method.getReturnType();
102         return (method.getParameterTypes().length == 0)
103             && (Void.TYPE != returnType)
104             && !name.startsWith("jjt")
105             && !name.equals("toString")
106             && !name.equals("getScope")
107             && !name.equals("getClass")
108             && !name.equals("getFinallyBlock")
109             && !name.equals("getCatchBlocks")
110             && !name.equals("getTypeNameNode")
111             && !name.equals("getImportedNameNode")
112             && !name.equals("hashCode");
113     }
114 }