001    /*
002     * Cobertura - http://cobertura.sourceforge.net/
003     *
004     * Copyright (C) 2003 jcoverage ltd.
005     * Copyright (C) 2005 Mark Doliner <thekingant@users.sourceforge.net>
006     *
007     * Cobertura is free software; you can redistribute it and/or modify
008     * it under the terms of the GNU General Public License as published
009     * by the Free Software Foundation; either version 2 of the License,
010     * or (at your option) any later version.
011     *
012     * Cobertura is distributed in the hope that it will be useful, but
013     * WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015     * General Public License for more details.
016     *
017     * You should have received a copy of the GNU General Public License
018     * along with Cobertura; if not, write to the Free Software
019     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
020     * USA
021     */
022    
023    package net.sourceforge.cobertura.check;
024    
025    import gnu.getopt.Getopt;
026    import gnu.getopt.LongOpt;
027    
028    import java.io.File;
029    import java.io.FileInputStream;
030    import java.io.IOException;
031    import java.math.BigDecimal;
032    import java.util.HashMap;
033    import java.util.Iterator;
034    import java.util.Map;
035    import java.util.StringTokenizer;
036    import java.util.regex.Pattern;
037    
038    import net.sourceforge.cobertura.coverage.CoverageData;
039    import net.sourceforge.cobertura.coverage.InstrumentationPersistence;
040    import net.sourceforge.cobertura.util.Copyright;
041    
042    import org.apache.log4j.Logger;
043    
044    public class Main extends InstrumentationPersistence
045    {
046    
047            private static final Logger logger = Logger.getLogger(Main.class);
048    
049            Map minimumCoverageRates = new HashMap();
050            CoverageRate minimumCoverageRate;
051    
052            File instrumentationDirectory = new File(System.getProperty("user.dir"));
053    
054            void setInstrumentationDirectory(File instrumentationDirectory)
055            {
056                    this.instrumentationDirectory = instrumentationDirectory;
057            }
058    
059            double inRangeAndDivideByOneHundred(String coverageRateAsPercentage)
060            {
061                    return inRangeAndDivideByOneHundred(Integer.valueOf(
062                                    coverageRateAsPercentage).intValue());
063            }
064    
065            double inRangeAndDivideByOneHundred(int coverageRateAsPercentage)
066            {
067                    if ((coverageRateAsPercentage >= 0)
068                                    && (coverageRateAsPercentage <= 100))
069                    {
070                            return (double)coverageRateAsPercentage / 100;
071                    }
072                    throw new IllegalArgumentException(
073                                    "Invalid value, valid range is [0 .. 100]");
074            }
075    
076            void setMinimumCoverageRate(String minimumCoverageRate)
077            {
078                    StringTokenizer tokenizer = new StringTokenizer(minimumCoverageRate,
079                                    ":");
080                    minimumCoverageRates.put(Pattern.compile(tokenizer.nextToken()),
081                                    new CoverageRate(inRangeAndDivideByOneHundred(tokenizer
082                                                    .nextToken()), inRangeAndDivideByOneHundred(tokenizer
083                                                    .nextToken())));
084            }
085    
086            CoverageRate findMinimumCoverageRate(String classname)
087            {
088                    Iterator i = minimumCoverageRates.entrySet().iterator();
089                    while (i.hasNext())
090                    {
091                            Map.Entry entry = (Map.Entry)i.next();
092    
093                            Pattern pattern = (Pattern)entry.getKey();
094                            if (pattern.matcher(classname).matches())
095                            {
096                                    return (CoverageRate)entry.getValue();
097                            }
098                    }
099                    return minimumCoverageRate;
100            }
101    
102            public Main(String[] args) throws IOException
103            {
104                    Copyright.print(System.out);
105                    System.out.println("Cobertura coverage check");
106    
107                    LongOpt[] longOpts = new LongOpt[4];
108                    longOpts[0] = new LongOpt("branch", LongOpt.REQUIRED_ARGUMENT, null,
109                                    'b');
110                    longOpts[1] = new LongOpt("line", LongOpt.REQUIRED_ARGUMENT, null,
111                                    'l');
112                    longOpts[2] = new LongOpt("directory", LongOpt.REQUIRED_ARGUMENT,
113                                    null, 'd');
114                    longOpts[3] = new LongOpt("regex", LongOpt.REQUIRED_ARGUMENT, null,
115                                    'r');
116    
117                    Getopt g = new Getopt(getClass().getName(), args, ":b:l:d:r:",
118                                    longOpts);
119                    int c;
120    
121                    double branchCoverageRate = 0.8;
122                    double lineCoverageRate = 0.7;
123    
124                    while ((c = g.getopt()) != -1)
125                    {
126                            switch (c)
127                            {
128                                    case 'b':
129                                            branchCoverageRate = inRangeAndDivideByOneHundred(g
130                                                            .getOptarg());
131                                            break;
132    
133                                    case 'l':
134                                            lineCoverageRate = inRangeAndDivideByOneHundred(g
135                                                            .getOptarg());
136                                            break;
137    
138                                    case 'd':
139                                            setInstrumentationDirectory(new File(g.getOptarg()));
140                                            break;
141    
142                                    case 'r':
143                                            setMinimumCoverageRate(g.getOptarg());
144                                            break;
145                            }
146                    }
147    
148                    minimumCoverageRate = new CoverageRate(lineCoverageRate,
149                                    branchCoverageRate);
150    
151                    if (logger.isInfoEnabled())
152                    {
153                            logger.info("instrumentation directory: "
154                                            + instrumentationDirectory);
155                    }
156    
157                    merge(loadInstrumentation(new FileInputStream(new File(
158                                    instrumentationDirectory,
159                                    InstrumentationPersistence.FILE_NAME))));
160    
161                    if (logger.isInfoEnabled())
162                    {
163                            logger
164                                            .info("instrumentation has " + keySet().size()
165                                                            + " entries");
166                    }
167    
168                    Iterator i = keySet().iterator();
169                    while (i.hasNext())
170                    {
171                            String key = (String)i.next();
172    
173                            CoverageRate coverageRate = findMinimumCoverageRate(key);
174                            CoverageData instrumentation = getInstrumentation(key);
175    
176                            if (logger.isInfoEnabled())
177                            {
178                                    StringBuffer sb = new StringBuffer();
179                                    sb.append(key);
180                                    sb.append(", line: ");
181                                    sb.append(percentage(instrumentation.getLineCoverageRate()));
182                                    sb.append("% (");
183                                    sb.append(percentage(coverageRate.getLineCoverageRate()));
184                                    sb.append("%), branch: ");
185                                    sb
186                                                    .append(percentage(instrumentation
187                                                                    .getBranchCoverageRate()));
188                                    sb.append("% (");
189                                    sb.append(percentage(coverageRate.getBranchCoverageRate()));
190                                    sb.append("%)");
191                                    logger.info(sb.toString());
192                            }
193    
194                            if (instrumentation.getLineCoverageRate() < coverageRate
195                                            .getLineCoverageRate())
196                            {
197                                    StringBuffer sb = new StringBuffer();
198                                    sb.append(key);
199                                    sb.append(" line coverage rate of: ");
200                                    sb.append(percentage(instrumentation.getLineCoverageRate()));
201                                    sb.append("% (required: ");
202                                    sb.append(percentage(coverageRate.getLineCoverageRate()));
203                                    sb.append("%)");
204                                    System.out.println(sb.toString());
205                            }
206    
207                            if (instrumentation.getBranchCoverageRate() < coverageRate
208                                            .getBranchCoverageRate())
209                            {
210                                    StringBuffer sb = new StringBuffer();
211                                    sb.append(key);
212                                    sb.append(" branch coverage rate of: ");
213                                    sb
214                                                    .append(percentage(instrumentation
215                                                                    .getBranchCoverageRate()));
216                                    sb.append("% (required: ");
217                                    sb.append(percentage(coverageRate.getBranchCoverageRate()));
218                                    sb.append("%)");
219                                    System.out.println(sb.toString());
220                            }
221                    }
222            }
223    
224            private String percentage(double coverateRate)
225            {
226                    BigDecimal decimal = new BigDecimal(coverateRate * 100);
227                    return decimal.setScale(1, BigDecimal.ROUND_DOWN).toString();
228            }
229    
230            public static void main(String[] args) throws IOException
231            {
232                    new Main(args);
233            }
234    
235    }