Coverage Report - net.sf.statsvn.Main
 
Classes in this File Line Coverage Branch Coverage Complexity
Main
26%
40/153
20%
11/54
2.688
 
 1  
 /*
 2  
  StatCvs - CVS statistics generation
 3  
  Copyright (C) 2002  Lukasz Pekacki <lukasz@pekacki.de>
 4  
  http://statcvs.sf.net/
 5  
 
 6  
  This library is free software; you can redistribute it and/or
 7  
  modify it under the terms of the GNU Lesser General Public
 8  
  License as published by the Free Software Foundation; either
 9  
  version 2.1 of the License, or (at your option) any later version.
 10  
 
 11  
  This library is distributed in the hope that it will be useful,
 12  
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  
  Lesser General Public License for more details.
 15  
 
 16  
  You should have received a copy of the GNU Lesser General Public
 17  
  License along with this library; if not, write to the Free Software
 18  
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 19  
 
 20  
  $RCSfile: Main.java,v $
 21  
  Created on $Date: 2005/03/20 19:12:25 $
 22  
  */
 23  
 package net.sf.statsvn;
 24  
 
 25  
 import java.io.FileInputStream;
 26  
 import java.io.IOException;
 27  
 import java.io.InputStream;
 28  
 import java.io.PrintWriter;
 29  
 import java.io.StringWriter;
 30  
 import java.util.ArrayList;
 31  
 import java.util.List;
 32  
 import java.util.Locale;
 33  
 import java.util.logging.LogManager;
 34  
 
 35  
 import net.sf.statcvs.Messages;
 36  
 import net.sf.statcvs.input.LogSyntaxException;
 37  
 import net.sf.statcvs.model.Repository;
 38  
 import net.sf.statcvs.output.ConfigurationException;
 39  
 import net.sf.statcvs.output.ConfigurationOptions;
 40  
 import net.sf.statcvs.output.ReportConfig;
 41  
 import net.sf.statcvs.pages.ReportSuiteMaker;
 42  
 import net.sf.statsvn.input.Builder;
 43  
 import net.sf.statsvn.input.RepositoryFileManager;
 44  
 import net.sf.statsvn.input.SvnLogfileParser;
 45  
 import net.sf.statsvn.output.SvnCommandLineParser;
 46  
 import net.sf.statsvn.output.SvnConfigurationOptions;
 47  
 import net.sf.statsvn.util.SvnStartupUtils;
 48  
 import net.sf.statsvn.util.SvnVersionMismatchException;
 49  
 
 50  
 /**
 51  
  * StatSvn Main Class; it starts the application and controls command-line
 52  
  * related stuff
 53  
  * 
 54  
  * @author Lukasz Pekacki
 55  
  * @author Richard Cyganiak
 56  
  * @version $Id: Main.java,v 1.47 2005/03/20 19:12:25 squig Exp $
 57  
  */
 58  
 public final class Main {
 59  
         private static final int KB_IN_ONE_MB = 1024;
 60  
 
 61  
         private static final int NUMBER_OF_MS_IN_ONE_SEC = 1000;
 62  
 
 63  3
         private static final LogManager LM = LogManager.getLogManager();
 64  
 
 65  
         /**
 66  
          * A utility class (only static methods) should be final and have a private
 67  
          * constructor.
 68  
          */
 69  0
         private Main() {
 70  0
         }
 71  
 
 72  
         /**
 73  
          * Main method of StatSVN
 74  
          * 
 75  
          * @param args
 76  
          *            command line options
 77  
          */
 78  
         public static void main(final String[] args) {
 79  0
                 init();
 80  0
                 verifyArguments(args);
 81  0
                 generate();
 82  0
                 System.exit(0);
 83  0
         }
 84  
 
 85  
         private static void verifyArguments(final String[] args) {
 86  0
                 if (args.length == 0) {
 87  0
                         printProperUsageAndExit();
 88  
                 }
 89  0
                 if (args.length == 1) {
 90  0
                         final String arg = args[0].toLowerCase(Locale.getDefault());
 91  0
                         if (arg.equals("-h") || arg.equals("-help")) {
 92  0
                                 printProperUsageAndExit();
 93  0
                         } else if (arg.equals("-version")) {
 94  0
                                 printVersionAndExit();
 95  
                         }
 96  
                 }
 97  
 
 98  
                 try {
 99  0
                         new SvnCommandLineParser(args).parse();
 100  0
                 } catch (final ConfigurationException cex) {
 101  0
                         SvnConfigurationOptions.getTaskLogger().error(cex.getMessage());
 102  0
                         System.exit(1);
 103  0
                 }
 104  0
         }
 105  
 
 106  
         public static void generate() {
 107  
                 try {
 108  0
                         final boolean isNewerDiffPossible = SvnStartupUtils.checkDiffPerRevPossible(SvnStartupUtils.checkSvnVersionSufficient());
 109  
                         // fall-back to older option.
 110  0
                         if (!isNewerDiffPossible) {
 111  0
                                 SvnConfigurationOptions.setLegacyDiff(true);
 112  
                         }
 113  
 
 114  0
                         SvnStartupUtils.checkRepoRootAvailable();
 115  0
                         generateDefaultHTMLSuite();
 116  0
                 } catch (final ConfigurationException cex) {
 117  0
                         SvnConfigurationOptions.getTaskLogger().error(cex.getMessage());
 118  0
                         System.exit(1);
 119  0
                 } catch (final LogSyntaxException lex) {
 120  0
                         printLogErrorMessageAndExit(lex.getMessage());
 121  0
                 } catch (final IOException ioex) {
 122  0
                         printIoErrorMessageAndExit(ioex.getMessage());
 123  0
                 } catch (final OutOfMemoryError oome) {
 124  0
                         printOutOfMemMessageAndExit();
 125  0
                 } catch (final SvnVersionMismatchException ever) {
 126  0
                         printErrorMessageAndExit(ever.getMessage());
 127  0
                 }
 128  0
         }
 129  
 
 130  
         public static void init() {
 131  0
                 Messages.setPrimaryResource("net.sf.statsvn.statcvs"); // primary is
 132  
                 // statcvs.properties in net.sf.statsvn
 133  
 
 134  0
                 SvnConfigurationOptions.getTaskLogger().info(Messages.getString("PROJECT_NAME") + Messages.NL);
 135  0
         }
 136  
 
 137  
         private static void initLogManager(final String loggingProperties) {
 138  3
                 InputStream stream = null;
 139  
                 try {
 140  6
                         stream = Main.class.getResourceAsStream(loggingProperties);
 141  3
                         LM.readConfiguration(stream);
 142  0
                 } catch (final IOException e) {
 143  0
                         SvnConfigurationOptions.getTaskLogger().error("ERROR: Logging could not be initialized!");
 144  
                 } finally {
 145  3
                         if (stream != null) {
 146  
                                 try {
 147  3
                                         stream.close();
 148  0
                                 } catch (final IOException e) {
 149  0
                                         SvnConfigurationOptions.getTaskLogger().error("ERROR: could not close stream!");
 150  3
                                 }
 151  
                         }
 152  
                 }
 153  3
         }
 154  
 
 155  
         private static void printProperUsageAndExit() {
 156  0
                 final String cr = System.getProperty("line.separator");
 157  0
                 SvnConfigurationOptions.getTaskLogger().error(
 158  
                 // max. 80 chars
 159  
                         // 12345678901234567890123456789012345678901234567890123456789012345678901234567890
 160  
                         "Usage: java -jar statsvn.jar [options] <logfile> <directory>" + cr + cr + "Required parameters:" + cr
 161  
                                 + "  <logfile>          path to the svn logfile of the module" + cr
 162  
                                 + "  <directory>        path to the directory of the checked out module" + cr + cr 
 163  
                                 + "Some options:" + cr
 164  
                                 + "  -version           print the version information and exit" + cr  
 165  
                                 + "  -output-dir <dir>  directory where HTML suite will be saved" + cr
 166  
                                 + "  -include <pattern> include only files matching pattern, e.g. **/*.c;**/*.h" + cr
 167  
                                 + "  -exclude <pattern> exclude matching files, e.g. tests/**;docs/**" + cr
 168  
                                 + "  -tags <regexp>     show matching tags in lines of code chart, e.g. version-.*" + cr
 169  
                                 + "  -title <title>     Project title to be used in reports" + cr 
 170  
                                 + "  -viewvc <url>      integrate with ViewVC installation at <url>" +cr
 171  
                                 + "  -trac <url>        integrate with Trac at <url>" + cr
 172  
                                 + "  -bugzilla <url>    integrate with Bugzilla installation at <url>" + cr 
 173  
                                 + "  -username <svnusername> username to pass to svn" + cr
 174  
                                 + "  -password <svnpassword> password to pass to svn" + cr 
 175  
                                 + "  -verbose           print extra progress information" + cr
 176  
                                 + "  -xdoc                 optional switch output to xdoc" + cr 
 177  0
                                 + "  -xml                  optional switch output to xml" + cr 
 178  0
                                 + "  -threads <int>        how many threads for svn diff (default: 25)" + cr
 179  
                                 + "  -concurrencyThreshold <millisec> switch to concurrent svn diff if 1st call>threshold (default: 4000)" + cr
 180  
                                 + "  -dump                 dump the Repository content on console" + cr
 181  0
                                 + "  -tags-dir <directory> optional, specifies the director for tags (default '/tags/')" + cr + cr
 182  0
                                 + "Full options list: http://www.statsvn.org");
 183  0
                 System.exit(1);
 184  0
         }
 185  
 
 186  0
         private static void printVersionAndExit() {
 187  0
                 SvnConfigurationOptions.getTaskLogger().error("Version " + Messages.getString("PROJECT_VERSION"));
 188  0
                 System.exit(1);
 189  0
         }
 190  
 
 191  
         private static void printOutOfMemMessageAndExit() {
 192  0
                 SvnConfigurationOptions.getTaskLogger().error("OutOfMemoryError.");
 193  0
                 SvnConfigurationOptions.getTaskLogger().error("Try running java with the -mx option (e.g. -mx128m for 128Mb).");
 194  0
                 System.exit(1);
 195  0
         }
 196  
 
 197  
         private static void printLogErrorMessageAndExit(final String message) {
 198  0
                 SvnConfigurationOptions.getTaskLogger().error("Logfile parsing failed.");
 199  0
                 SvnConfigurationOptions.getTaskLogger().error(message);
 200  0
                 System.exit(1);
 201  0
         }
 202  
 
 203  
         private static void printIoErrorMessageAndExit(final String message) {
 204  0
                 SvnConfigurationOptions.getTaskLogger().error(message);
 205  0
                 System.exit(1);
 206  0
         }
 207  0
 
 208  0
         public static String printStackTrace(final Exception e) {
 209  0
                 try {
 210  0
                         final StringWriter sw = new StringWriter();
 211  0
                         final PrintWriter pw = new PrintWriter(sw);
 212  0
                         e.printStackTrace(pw);
 213  0
                         return sw.toString();
 214  0
                 } catch (final Exception e2) {
 215  0
                         if (e != null) {
 216  0
                                 return e.getMessage();
 217  
                         } else {
 218  0
                                 return "";
 219  0
                         }
 220  0
                 }
 221  
         }
 222  
 
 223  
         private static void printErrorMessageAndExit(final String message) {
 224  0
                 SvnConfigurationOptions.getTaskLogger().error(message);
 225  0
                 System.exit(1);
 226  0
         }
 227  
 
 228  
         /**
 229  
          * Generates HTML report. {@link net.sf.statsvn.output.ConfigurationOptions}
 230  
          * must be initialized before calling this method.
 231  
          * 
 232  
          * @throws LogSyntaxException
 233  
          *             if the logfile contains unexpected syntax
 234  0
          * @throws IOException
 235  0
          *             if some file can't be read or written
 236  
          * @throws ConfigurationException
 237  
          *             if a required ConfigurationOption was not set
 238  
          */
 239  
         public static void generateDefaultHTMLSuite() throws LogSyntaxException, IOException, ConfigurationException {
 240  0
                 generateDefaultHTMLSuite(new RepositoryFileManager(ConfigurationOptions.getCheckedOutDirectory()));
 241  0
         }
 242  
 
 243  
         /**
 244  
          * Generates HTML report. {@link net.sf.statsvn.output.ConfigurationOptions}
 245  
          * must be initialized before calling this method.
 246  
          * 
 247  
          * @param externalRepositoryFileManager
 248  
          *            RepositoryFileManager which is used to access the files in the
 249  
          *            repository.
 250  
          * 
 251  
          * @throws LogSyntaxException
 252  
          *             if the logfile contains unexpected syntax
 253  
          * @throws IOException
 254  3
          *             if some file can't be read or written
 255  0
          * @throws ConfigurationException
 256  
          *             if a required ConfigurationOption was not set
 257  3
          */
 258  0
         public static void generateDefaultHTMLSuite(final RepositoryFileManager repFileMan) throws LogSyntaxException, IOException, ConfigurationException {
 259  
 
 260  0
                 if (ConfigurationOptions.getLogFileName() == null) {
 261  3
                         throw new ConfigurationException("Missing logfile name");
 262  3
                 }
 263  0
                 if (ConfigurationOptions.getCheckedOutDirectory() == null) {
 264  3
                         throw new ConfigurationException("Missing checked out directory");
 265  
                 }
 266  3
 
 267  0
                 final long memoryUsedOnStart = Runtime.getRuntime().totalMemory();
 268  0
                 final long startTime = System.currentTimeMillis();
 269  3
 
 270  3
                 initLogManager(ConfigurationOptions.getLoggingProperties());
 271  
 
 272  3
                 SvnConfigurationOptions.getTaskLogger().info(
 273  3
                         "Parsing SVN log '" + ConfigurationOptions.getLogFileName() + "' exclude pattern '" + ConfigurationOptions.getExcludePattern() + "'");
 274  
 
 275  3
                 final FileInputStream logFile = new FileInputStream(ConfigurationOptions.getLogFileName());
 276  0
                 final Builder builder = new Builder(repFileMan, ConfigurationOptions.getIncludePattern(), ConfigurationOptions.getExcludePattern(),
 277  
                         ConfigurationOptions.getSymbolicNamesPattern());
 278  3
                 new SvnLogfileParser(repFileMan, logFile, builder).parse();
 279  0
                 logFile.close();
 280  
 
 281  0
                 if (ConfigurationOptions.getProjectName() == null) {
 282  3
                         ConfigurationOptions.setProjectName(builder.getProjectName());
 283  
                 }
 284  3
                 if (ConfigurationOptions.getWebRepository() != null) {
 285  3
                         ConfigurationOptions.getWebRepository().setAtticFileNames(builder.getAtticFileNames());
 286  
                 }
 287  
 
 288  3
                 SvnConfigurationOptions.getTaskLogger().info(
 289  
                         "Generating report for " + ConfigurationOptions.getProjectName() + " into " + ConfigurationOptions.getOutputDir());
 290  3
                 SvnConfigurationOptions.getTaskLogger().info("Using " + ConfigurationOptions.getCssHandler());
 291  0
                 final Repository content = builder.createRepository();
 292  3
 
 293  3
                 // make JFreeChart work on systems without GUI
 294  3
                 System.setProperty("java.awt.headless", "true");
 295  
 
 296  3
                 final ReportConfig config = new ReportConfig(content, ConfigurationOptions.getProjectName(), ConfigurationOptions.getOutputDir(), ConfigurationOptions
 297  
                         .getMarkupSyntax(), ConfigurationOptions.getCssHandler());
 298  3
                 config.setWebRepository(ConfigurationOptions.getWebRepository());
 299  0
                 config.setWebBugtracker(ConfigurationOptions.getWebBugtracker());
 300  0
                 config.setNonDeveloperLogins(ConfigurationOptions.getNonDeveloperLogins());
 301  
 
 302  3
                 validate(config);
 303  
 
 304  3
                 if (SvnConfigurationOptions.isDumpContent()) {
 305  0
                         new RepoDump(content).dump();
 306  
                 } else {
 307  
                         // add new reports
 308  0
                         final List extraReports = new ArrayList();
 309  3
 
 310  0
                         if ("xml".equalsIgnoreCase(ConfigurationOptions.getOutputFormat())) {
 311  0
                                 new ReportSuiteMaker(config, ConfigurationOptions.getNotes(), extraReports).toXml();
 312  1
                         } else {
 313  1
                                 //                                extraReports.add(new RepoMapPageMaker(config).toFile());
 314  
                                 //                                extraReports.add(new ChurnPageMaker(config).toFile());
 315  1
                                 new ReportSuiteMaker(config, ConfigurationOptions.getNotes(), extraReports).toFile().write();
 316  1
                         }
 317  1
                 }
 318  0
                 final long endTime = System.currentTimeMillis();
 319  0
                 final long memoryUsedOnEnd = Runtime.getRuntime().totalMemory();
 320  3
 
 321  0
                 SvnConfigurationOptions.getTaskLogger().info("runtime: " + (((double) endTime - startTime) / NUMBER_OF_MS_IN_ONE_SEC) + " seconds");
 322  0
                 SvnConfigurationOptions.getTaskLogger().info("memory usage: " + (((double) memoryUsedOnEnd - memoryUsedOnStart) / KB_IN_ONE_MB) + " kb");
 323  0
         }
 324  3
 
 325  
         private static void validate(final ReportConfig config) {
 326  0
                 if (config.getRepository() == null || config.getRepository().getRoot() == null || config.getRepository().getDirectories() == null) {
 327  0
                         printErrorMessageAndExit("The repository object is not valid. Please check your settings." + System.getProperty("line.separator")
 328  
                                 + "Is the log file empty? Do you run from a checked out directory? Do you have non-committed items?");
 329  
                 }
 330  0
         }
 331  
 }