Coverage Report - net.sourceforge.cobertura.coveragedata.CoverageDataContainer
 
Classes in this File Line Coverage Branch Coverage Complexity
CoverageDataContainer
N/A
N/A
2.455
 
 1  
 /*
 2  
  * Cobertura - http://cobertura.sourceforge.net/
 3  
  *
 4  
  * Copyright (C) 2003 jcoverage ltd.
 5  
  * Copyright (C) 2005 Mark Doliner
 6  
  * Copyright (C) 2005 Jeremy Thomerson
 7  
  * Copyright (C) 2005 Mark Sinke
 8  
  *
 9  
  * Cobertura is free software; you can redistribute it and/or modify
 10  
  * it under the terms of the GNU General Public License as published
 11  
  * by the Free Software Foundation; either version 2 of the License,
 12  
  * or (at your option) any later version.
 13  
  *
 14  
  * Cobertura is distributed in the hope that it will be useful, but
 15  
  * WITHOUT ANY WARRANTY; without even the implied warranty of
 16  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 17  
  * General Public License for more details.
 18  
  *
 19  
  * You should have received a copy of the GNU General Public License
 20  
  * along with Cobertura; if not, write to the Free Software
 21  
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 22  
  * USA
 23  
  */
 24  
 
 25  
 package net.sourceforge.cobertura.coveragedata;
 26  
 
 27  
 import java.io.Serializable;
 28  
 import java.util.HashMap;
 29  
 import java.util.Iterator;
 30  
 import java.util.Map;
 31  
 import java.util.Collections;
 32  
 
 33  
 /**
 34  
  * <p>
 35  
  * Coverage data information is typically serialized to a file.
 36  
  * </p>
 37  
  *
 38  
  * <p>
 39  
  * This class implements HasBeenInstrumented so that when cobertura
 40  
  * instruments itself, it will omit this class.  It does this to
 41  
  * avoid an infinite recursion problem because instrumented classes
 42  
  * make use of this class.
 43  
  * </p>
 44  
  */
 45  
 public abstract class CoverageDataContainer
 46  
                 implements CoverageData, HasBeenInstrumented, Serializable
 47  
 {
 48  
 
 49  
    private static final long serialVersionUID = 2;
 50  
 
 51  
         /**
 52  
          * Each key is the name of a child, usually stored as a String or
 53  
          * an Integer object.  Each value is information about the child,
 54  
          * stored as an object that implements the CoverageData interface.
 55  
          */
 56  
         Map children = Collections.synchronizedMap(new HashMap());
 57  
 
 58  
         /**
 59  
          * Determine if this CoverageDataContainer is equal to
 60  
          * another one.  Subclasses should override this and
 61  
          * make sure they implement the hashCode method.
 62  
          *
 63  
          * @param obj An object to test for equality.
 64  
          * @return True if the objects are equal.
 65  
          */
 66  
         public boolean equals(Object obj)
 67  
         {
 68  
                 if (this == obj)
 69  
                         return true;
 70  
                 if ((obj == null) || !(obj.getClass().equals(this.getClass())))
 71  
                         return false;
 72  
 
 73  
                 CoverageDataContainer coverageDataContainer = (CoverageDataContainer)obj;
 74  
                 return this.children.equals(coverageDataContainer.children);
 75  
         }
 76  
 
 77  
         /**
 78  
          * @return The average branch coverage rate for all children
 79  
          *         in this container.
 80  
          */
 81  
         public double getBranchCoverageRate()
 82  
         {
 83  
                 int number = 0;
 84  
                 int numberCovered = 0;
 85  
                 Iterator iter = this.children.values().iterator();
 86  
                 while (iter.hasNext())
 87  
                 {
 88  
                         CoverageData coverageContainer = (CoverageData)iter.next();
 89  
                         number += coverageContainer.getNumberOfValidBranches();
 90  
                         numberCovered += coverageContainer.getNumberOfCoveredBranches();
 91  
                 }
 92  
                 if (number == 0)
 93  
                 {
 94  
                         // no branches, therefore 100% branch coverage.
 95  
                         return 1d;
 96  
                 }
 97  
                 return (double)numberCovered / number;
 98  
         }
 99  
 
 100  
         /**
 101  
          * Get a child from this container with the specified
 102  
          * key.
 103  
          * @param name The key used to lookup the child in the
 104  
          *        map.
 105  
          * @return The child object, if found, or null if not found.
 106  
          */
 107  
         public CoverageData getChild(String name)
 108  
         {
 109  
                 return (CoverageData)this.children.get(name);
 110  
         }
 111  
 
 112  
         /**
 113  
          * @return The average line coverage rate for all children
 114  
          *         in this container.  This number will be a decimal
 115  
          *         between 0 and 1, inclusive.
 116  
          */
 117  
         public double getLineCoverageRate()
 118  
         {
 119  
                 int number = 0;
 120  
                 int numberCovered = 0;
 121  
                 Iterator iter = this.children.values().iterator();
 122  
                 while (iter.hasNext())
 123  
                 {
 124  
                         CoverageData coverageContainer = (CoverageData)iter.next();
 125  
                         number += coverageContainer.getNumberOfValidLines();
 126  
                         numberCovered += coverageContainer.getNumberOfCoveredLines();
 127  
                 }
 128  
                 if (number == 0)
 129  
                 {
 130  
                         // no lines, therefore 100% line coverage.
 131  
                         return 1d;
 132  
                 }
 133  
                 return (double)numberCovered / number;
 134  
         }
 135  
 
 136  
         /**
 137  
          * @return The number of children in this container.
 138  
          */
 139  
         public int getNumberOfChildren()
 140  
         {
 141  
                 return this.children.size();
 142  
         }
 143  
 
 144  
         public int getNumberOfCoveredBranches()
 145  
         {
 146  
                 int number = 0;
 147  
                 Iterator iter = this.children.values().iterator();
 148  
                 while (iter.hasNext())
 149  
                 {
 150  
                         CoverageData coverageContainer = (CoverageData)iter.next();
 151  
                         number += coverageContainer.getNumberOfCoveredBranches();
 152  
                 }
 153  
                 return number;
 154  
         }
 155  
 
 156  
         public int getNumberOfCoveredLines()
 157  
         {
 158  
                 int number = 0;
 159  
                 Iterator iter = this.children.values().iterator();
 160  
                 while (iter.hasNext())
 161  
                 {
 162  
                         CoverageData coverageContainer = (CoverageData)iter.next();
 163  
                         number += coverageContainer.getNumberOfCoveredLines();
 164  
                 }
 165  
                 return number;
 166  
         }
 167  
 
 168  
         public int getNumberOfValidBranches()
 169  
         {
 170  
                 int number = 0;
 171  
                 Iterator iter = this.children.values().iterator();
 172  
                 while (iter.hasNext())
 173  
                 {
 174  
                         CoverageData coverageContainer = (CoverageData)iter.next();
 175  
                         number += coverageContainer.getNumberOfValidBranches();
 176  
                 }
 177  
                 return number;
 178  
         }
 179  
 
 180  
         public int getNumberOfValidLines()
 181  
         {
 182  
                 int number = 0;
 183  
                 Iterator iter = this.children.values().iterator();
 184  
                 while (iter.hasNext())
 185  
                 {
 186  
                         CoverageData coverageContainer = (CoverageData)iter.next();
 187  
                         number += coverageContainer.getNumberOfValidLines();
 188  
                 }
 189  
                 return number;
 190  
         }
 191  
 
 192  
         /**
 193  
          * It is highly recommended that classes extending this
 194  
          * class override this hashCode method and generate a more
 195  
          * effective hash code.
 196  
          */
 197  
         public int hashCode()
 198  
         {
 199  
                 return this.children.size();
 200  
         }
 201  
 
 202  
         /**
 203  
          * Merge two <code>CoverageDataContainer</code>s.
 204  
          *
 205  
          * @param coverageData The container to merge into this one.
 206  
          */
 207  
         public void merge(CoverageData coverageData)
 208  
         {
 209  
                 CoverageDataContainer container = (CoverageDataContainer)coverageData;
 210  
                 Iterator iter = container.children.keySet().iterator();
 211  
                 while (iter.hasNext())
 212  
                 {
 213  
                         Object key = iter.next();
 214  
                         CoverageData newChild = (CoverageData)container.children.get(key);
 215  
                         CoverageData existingChild = (CoverageData)this.children.get(key);
 216  
                         if (existingChild != null)
 217  
                         {
 218  
                                 existingChild.merge(newChild);
 219  
                         }
 220  
                         else
 221  
                         {
 222  
                                 // TODO: Shouldn't we be cloning newChild here?  I think so that
 223  
                                 //       would be better... but we would need to override the
 224  
                                 //       clone() method all over the place?
 225  
                                 this.children.put(key, newChild);
 226  
                         }
 227  
                 }
 228  
         }
 229  
 
 230  
 }