Clover coverage report - PMD - 3.7
Coverage timestamp: Wed May 31 2006 09:25:59 EDT
file stats: LOC: 230   Methods: 10
NCLOC: 162   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
ReportTree.java 56.2% 50% 30% 50.7%
coverage coverage
 1    package net.sourceforge.pmd.dfa.report;
 2   
 3    import net.sourceforge.pmd.RuleViolation;
 4    import net.sourceforge.pmd.IRuleViolation;
 5   
 6    import java.lang.reflect.InvocationTargetException;
 7    import java.lang.reflect.Method;
 8    import java.util.ArrayList;
 9    import java.util.Iterator;
 10    import java.util.List;
 11    import java.util.StringTokenizer;
 12   
 13    public class ReportTree {
 14   
 15    private PackageNode rootNode = new PackageNode("");
 16    private AbstractReportNode level;
 17   
 18    private class TreeIterator implements Iterator {
 19   
 20    private AbstractReportNode iterNode = rootNode;
 21    private boolean hasNextFlag;
 22   
 23  0 public void remove() {
 24  0 throw new UnsupportedOperationException();
 25    }
 26   
 27  0 public boolean hasNext() {
 28  0 this.hasNextFlag = true;
 29  0 return this.getNext() != null;
 30    }
 31   
 32  0 public Object next() {
 33   
 34  0 if (!this.hasNextFlag) {
 35  0 this.getNext();
 36    } else {
 37  0 this.hasNextFlag = false;
 38    }
 39   
 40  0 if (this.iterNode instanceof ViolationNode) {
 41  0 return ((ViolationNode) this.iterNode).getRuleViolation();
 42    }
 43  0 return null;
 44    }
 45   
 46    /**
 47    * It's some kind of left-right-middle search (postorder).
 48    * It always returns only
 49    * leafs. The first node he returns is the most left handed leaf he can
 50    * found. Now he's looking for siblings and if there are any, he starts
 51    * searching for the next most left handed leaf. If there are no
 52    * siblings he goes up to his parent and starts looking for siblings.
 53    * If there are any he starts searching for the next most left handed
 54    * leaf again. And so on ... until he wants to get the parent of the
 55    * root node. Because there is no one, the search stops.
 56    */
 57   
 58  0 private Object getNext() {
 59  0 AbstractReportNode node;
 60   
 61  0 while (true) {
 62  0 if (this.iterNode.isLeaf()) {
 63   
 64  0 while ((node = (this.iterNode).getNextSibling()) == null) {
 65   
 66  0 node = this.iterNode.getParent();
 67  0 if (node == null) {
 68  0 return null;
 69    } else {
 70  0 this.iterNode = node;
 71    }
 72    }
 73   
 74  0 this.iterNode = node;
 75  0 if (this.iterNode.isLeaf()) {
 76  0 return this.iterNode;
 77    } else {
 78  0 continue;
 79    }
 80    } else {
 81  0 this.iterNode = this.iterNode.getFirstChild();
 82  0 if (this.iterNode.isLeaf()) {
 83  0 return this.iterNode;
 84    } else {
 85  0 continue;
 86    }
 87    }
 88    }
 89    }
 90    }
 91   
 92   
 93  0 public Iterator iterator() {
 94  0 return new TreeIterator();
 95    }
 96   
 97  0 public int size() {
 98  0 int count = 0;
 99  0 for (Iterator i = iterator(); i.hasNext();) {
 100  0 i.next();
 101  0 count++;
 102    }
 103  0 return count;
 104    }
 105   
 106  0 public AbstractReportNode getRootNode() {
 107  0 return rootNode;
 108    }
 109   
 110    /**
 111    * Adds the RuleViolation to the tree. Splits the package name. Each
 112    * package, class and violation gets there own tree node.
 113    */
 114  2660 public void addRuleViolation(IRuleViolation violation) {
 115  2660 String pack = violation.getPackageName();
 116  2660 String[] a = {};
 117  2660 if (pack == null) {
 118  0 a = new String[]{""};
 119  2660 } else if (pack.indexOf(".") != -1) {
 120    // TODO Remove when minimal runtime support is >= JDK 1.4
 121  2 try {
 122  2 Method split = String.class.getMethod("split", new Class[]{String.class});
 123  2 if (split != null) {
 124    // // Compatible with >= JDK 1.4
 125  2 Object[] tmp = (Object[]) split.invoke(pack, new Object[]{"\\."});
 126  2 a = new String[tmp.length];
 127  2 for (int i = 0; i < tmp.length; i++) {
 128  4 a[i] = (String) tmp[i];
 129    }
 130    }
 131    } catch (IllegalAccessException e) {
 132  0 e.printStackTrace();
 133  0 throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
 134    } catch (IllegalArgumentException e) {
 135  0 e.printStackTrace();
 136  0 throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
 137    } catch (InvocationTargetException e) {
 138  0 e.printStackTrace();
 139  0 throw new InternalError("Runtime reports to be >= JDK 1.4 yet String.split(java.lang.String) is broken.");
 140    } catch (NoSuchMethodException nsme) {
 141    // Compatible with < JDK 1.4
 142  0 StringTokenizer toker = new StringTokenizer(pack, ".");
 143  0 List parts = new ArrayList();
 144  0 while (toker.hasMoreTokens()) {
 145  0 parts.add(toker.nextToken());
 146    }
 147  0 a = (String[]) parts.toArray(new String[parts.size()]);
 148    }
 149    } else {
 150  2658 a = new String[]{pack};
 151    }
 152   
 153  2660 this.level = this.rootNode;
 154  2660 String plugedPackageName = "";
 155   
 156  2660 for (int i = 0; i < a.length; i++) {
 157  2662 String packageName = a[i];
 158  2662 plugedPackageName += packageName + ".";
 159   
 160  2662 if (!this.isStringInLevel(plugedPackageName)) {
 161  543 PackageNode node = new PackageNode(plugedPackageName);
 162  543 this.level.addFirst(node);
 163    // gotoLevel
 164  543 this.level = node;
 165    }
 166    }
 167   
 168  2660 String cl = violation.getClassName();
 169   
 170  2660 if (!this.isStringInLevel(cl)) {
 171  549 ClassNode node = new ClassNode(cl);
 172  549 this.level.addFirst(node);
 173    // gotoLevel
 174  549 this.level = node;
 175    }
 176   
 177    /*
 178    * Filters dublicated rule violations. Like the comparator in
 179    * RuleViolation if he already exists.
 180    */
 181  2660 ViolationNode tmp = new ViolationNode(violation);
 182  2660 if (!this.equalsNodeInLevel(this.level, tmp)) {
 183  2651 this.level.add(tmp);
 184    }
 185    }
 186   
 187    /**
 188    * Checks if node is a child of the level node.
 189    */
 190  2660 private boolean equalsNodeInLevel(AbstractReportNode level, AbstractReportNode node) {
 191  2660 for (int i = 0; i < level.getChildCount(); i++) {
 192  41840 if ((level.getChildAt(i)).equalsNode(node)) {
 193  9 return true;
 194    }
 195    }
 196  2651 return false;
 197    }
 198   
 199    /**
 200    * Checks if the packageName or the className is a child of the current
 201    * (this.level) node. If it's true, the current node changes to the
 202    * child node.
 203    */
 204  5322 private boolean isStringInLevel(String str) {
 205   
 206  5322 for (int i = 0; i < this.level.getChildCount(); i++) {
 207  4238 AbstractReportNode child = this.level.getChildAt(i);
 208  4238 String tmp = null;
 209   
 210  4238 if (child instanceof PackageNode) {
 211  2119 tmp = ((PackageNode) child).getPackageName();
 212    }
 213  4238 if (child instanceof ClassNode) {
 214  2119 tmp = ((ClassNode) child).getClassName();
 215    }
 216   
 217  4238 if (tmp == null) {
 218  0 return false;
 219    }
 220   
 221  4238 if (tmp.equals(str)) {
 222    // goto level
 223  4230 this.level = child;
 224  4230 return true;
 225    }
 226    }
 227  1092 return false;
 228    }
 229   
 230    }