Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 102 |  | Methods: | 8
| NCLOC: | 79 |  | Classes: | 2
Source file | Conditionals | Statements | Methods | TOTAL
AttributeAxisIterator.java | 94.4% | 97.1% | 100% | 96.7% |

1 |  | /**
2 |  | * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3 |  | */
4 |  | package net.sourceforge.pmd.jaxen;
5 |  |
6 |  | import net.sourceforge.pmd.ast.Node;
7 |  |
8 |  | import java.lang.reflect.Method;
9 |  | import java.util.ArrayList;
10 |  | import java.util.HashMap;
11 |  | import java.util.Iterator;
12 |  | import java.util.List;
13 |  | import java.util.Map;
14 |  |
15 |  | public class AttributeAxisIterator implements Iterator {
16 |  |
17 |  | private static class MethodWrapper {
18 |  | public Method method;
19 |  | public String name;
20 |  |
21 | 1611 | public MethodWrapper(Method m) {
22 | 1611 | this.method = m;
23 | 1611 | this.name = truncateMethodName(m.getName());
24 |  | }
25 |  |
26 | 1611 | private String truncateMethodName(String n) {
27 |  | // about 70% of the methods start with 'get', so this case goes first
28 | 1036 | if (n.startsWith("get")) return n.substring("get".length());
29 | 560 | if (n.startsWith("is")) return n.substring("is".length());
30 | 2 | if (n.startsWith("has")) return n.substring("has".length());
31 | 8 | if (n.startsWith("uses")) return n.substring("uses".length());
32 |  |
33 | 5 | return n;
34 |  | }
35 |  | }
36 |  |
37 |  | private Object currObj;
38 |  | private MethodWrapper[] methodWrappers;
39 |  | private int position;
40 |  | private Node node;
41 |  |
42 |  | private static Map methodCache = new HashMap();
43 |  |
44 | 920 | public AttributeAxisIterator(Node contextNode) {
45 | 920 | this.node = contextNode;
46 | 920 | if (!methodCache.containsKey(contextNode.getClass())) {
47 | 158 | Method[] preFilter = contextNode.getClass().getMethods();
48 | 158 | List postFilter = new ArrayList();
49 | 158 | for (int i = 0; i < preFilter.length; i++) {
50 | 8316 | if (isAttributeAccessor(preFilter[i])) {
51 | 1611 | postFilter.add(new MethodWrapper(preFilter[i]));
52 |  | }
53 |  | }
54 | 158 | methodCache.put(contextNode.getClass(), postFilter.toArray(new MethodWrapper[postFilter.size()]));
55 |  | }
56 | 920 | this.methodWrappers = (MethodWrapper[]) methodCache.get(contextNode.getClass());
57 |  |
58 | 920 | this.position = 0;
59 | 920 | this.currObj = getNextAttribute();
60 |  | }
61 |  |
62 | 9799 | public Object next() {
63 | 9799 | if (currObj == null) {
64 | 0 | throw new IndexOutOfBoundsException();
65 |  | }
66 | 9799 | Object ret = currObj;
67 | 9799 | currObj = getNextAttribute();
68 | 9799 | return ret;
69 |  | }
70 |  |
71 | 11637 | public boolean hasNext() {
72 | 11637 | return currObj != null;
73 |  | }
74 |  |
75 | 1 | public void remove() {
76 | 1 | throw new UnsupportedOperationException();
77 |  | }
78 |  |
79 | 10719 | private Attribute getNextAttribute() {
80 | 10719 | if (position == methodWrappers.length) {
81 | 919 | return null;
82 |  | }
83 | 9800 | MethodWrapper m = methodWrappers[position++];
84 | 9800 | return new Attribute(node, m.name, m.method);
85 |  | }
86 |  |
87 | 8316 | protected boolean isAttributeAccessor(Method method) {
88 |  |
89 | 8316 | String methodName = method.getName();
90 |  |
91 | 8316 | return (Integer.TYPE == method.getReturnType() || Boolean.TYPE == method.getReturnType() || String.class == method.getReturnType())
92 |  | && (method.getParameterTypes().length == 0)
93 |  | && (Void.TYPE != method.getReturnType())
94 |  | && !methodName.startsWith("jjt")
95 |  | && !methodName.equals("toString")
96 |  | && !methodName.equals("getScope")
97 |  | && !methodName.equals("getClass")
98 |  | && !methodName.equals("getTypeNameNode")
99 |  | && !methodName.equals("getImportedNameNode")
100 |  | && !methodName.equals("hashCode");
101 |  | }
102 |  | }