Coverage Report - net.sf.statsvn.Main
 
Classes in this File Line Coverage Branch Coverage Complexity
Main
35%
61/174
27%
20/74
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  4
         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  4
                 InputStream stream = null;
 139  
                 try {
 140  8
                         stream = Main.class.getResourceAsStream(loggingProperties);
 141  4
                         LM.readConfiguration(stream);
 142  0
                 } catch (final IOException e) {
 143  0
                         SvnConfigurationOptions.getTaskLogger().error("ERROR: Logging could not be initialized!");
 144  
                 } finally {
 145  4
                         if (stream != null) {
 146  
                                 try {
 147  4
                                         stream.close();
 148  0
                                 } catch (final IOException e) {
 149  0
                                         SvnConfigurationOptions.getTaskLogger().error("ERROR: could not close stream!");
 150  4
                                 }
 151  
                         }
 152  
                 }
 153  4
         }
 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  
                                 + "  -concurrency-threshold <millisec> switch to concurrent svn diff if 1st call>threshold (default: 4000)" + cr
 180  
                                 + "  -dump                 dump the Repository content on console" + cr
 181  0
                         + "  -charset <charset> specify the charset to use for html/xdoc\n"
 182  0
                                 + "  -tags-dir <directory> optional, specifies the director for tags (default '/tags/')" + cr + cr
 183  0
                                 + "Full options list: http://www.statsvn.org");
 184  0
                 System.exit(1);
 185  0
         }
 186  0
 
 187  0
         private static void printVersionAndExit() {
 188  0
                 SvnConfigurationOptions.getTaskLogger().error("Version " + Messages.getString("PROJECT_VERSION"));
 189  0
                 System.exit(1);
 190  0
         }
 191  
 
 192  0
         private static void printOutOfMemMessageAndExit() {
 193  0
                 SvnConfigurationOptions.getTaskLogger().error("OutOfMemoryError.");
 194  0
                 SvnConfigurationOptions.getTaskLogger().error("Try running java with the -mx option (e.g. -mx128m for 128Mb).");
 195  0
                 System.exit(1);
 196  0
         }
 197  
 
 198  0
         private static void printLogErrorMessageAndExit(final String message) {
 199  0
                 SvnConfigurationOptions.getTaskLogger().error("Logfile parsing failed.");
 200  0
                 SvnConfigurationOptions.getTaskLogger().error(message);
 201  0
                 System.exit(1);
 202  0
         }
 203  
 
 204  0
         private static void printIoErrorMessageAndExit(final String message) {
 205  0
                 SvnConfigurationOptions.getTaskLogger().error(message);
 206  0
                 System.exit(1);
 207  0
         }
 208  0
 
 209  0
         public static String printStackTrace(final Exception e) {
 210  0
                 try {
 211  0
                         final StringWriter sw = new StringWriter();
 212  0
                         final PrintWriter pw = new PrintWriter(sw);
 213  0
                         e.printStackTrace(pw);
 214  0
                         return sw.toString();
 215  0
                 } catch (final Exception e2) {
 216  0
                         if (e != null) {
 217  0
                                 return e.getMessage();
 218  0
                         } else {
 219  0
                                 return "";
 220  0
                         }
 221  
                 }
 222  
         }
 223  
 
 224  0
         private static void printErrorMessageAndExit(final String message) {
 225  0
                 SvnConfigurationOptions.getTaskLogger().error(message);
 226  0
                 System.exit(1);
 227  0
         }
 228  
 
 229  
         /**
 230  
          * Generates HTML report. {@link net.sf.statsvn.output.ConfigurationOptions}
 231  
          * must be initialized before calling this method.
 232  
          * 
 233  
          * @throws LogSyntaxException
 234  0
          *             if the logfile contains unexpected syntax
 235  0
          * @throws IOException
 236  
          *             if some file can't be read or written
 237  
          * @throws ConfigurationException
 238  
          *             if a required ConfigurationOption was not set
 239  
          */
 240  0
         public static void generateDefaultHTMLSuite() throws LogSyntaxException, IOException, ConfigurationException {
 241  0
                 generateDefaultHTMLSuite(new RepositoryFileManager(ConfigurationOptions.getCheckedOutDirectory()));
 242  0
         }
 243  
 
 244  
         /**
 245  
          * Generates HTML report. {@link net.sf.statsvn.output.ConfigurationOptions}
 246  
          * must be initialized before calling this method.
 247  
          * 
 248  
          * @param externalRepositoryFileManager
 249  
          *            RepositoryFileManager which is used to access the files in the
 250  
          *            repository.
 251  
          * 
 252  
          * @throws LogSyntaxException
 253  
          *             if the logfile contains unexpected syntax
 254  3
          * @throws IOException
 255  0
          *             if some file can't be read or written
 256  
          * @throws ConfigurationException
 257  3
          *             if a required ConfigurationOption was not set
 258  0
          */
 259  
         public static void generateDefaultHTMLSuite(final RepositoryFileManager repFileMan) throws LogSyntaxException, IOException, ConfigurationException {
 260  0
 
 261  4
                 if (ConfigurationOptions.getLogFileName() == null) {
 262  3
                         throw new ConfigurationException("Missing logfile name");
 263  0
                 }
 264  4
                 if (ConfigurationOptions.getCheckedOutDirectory() == null) {
 265  0
                         throw new ConfigurationException("Missing checked out directory");
 266  3
                 }
 267  0
 
 268  1
                 final long memoryUsedOnStart = Runtime.getRuntime().totalMemory();
 269  4
                 final long startTime = System.currentTimeMillis();
 270  3
 
 271  1
                 initLogManager(ConfigurationOptions.getLoggingProperties());
 272  3
 
 273  4
                 SvnConfigurationOptions.getTaskLogger().info(
 274  
                         "Parsing SVN log '" + ConfigurationOptions.getLogFileName() + "' exclude pattern '" + ConfigurationOptions.getExcludePattern() + "'");
 275  3
 
 276  1
                 final FileInputStream logFile = new FileInputStream(ConfigurationOptions.getLogFileName());
 277  1
                 final Builder builder = new Builder(repFileMan, ConfigurationOptions.getIncludePattern(), ConfigurationOptions.getExcludePattern(),
 278  3
                         ConfigurationOptions.getSymbolicNamesPattern());
 279  1
                 new SvnLogfileParser(repFileMan, logFile, builder).parse();
 280  1
                 logFile.close();
 281  0
 
 282  4
                 if (ConfigurationOptions.getProjectName() == null) {
 283  0
                         ConfigurationOptions.setProjectName(builder.getProjectName());
 284  3
                 }
 285  4
                 if (ConfigurationOptions.getWebRepository() != null) {
 286  0
                         ConfigurationOptions.getWebRepository().setAtticFileNames(builder.getAtticFileNames());
 287  
                 }
 288  3
 
 289  1
                 SvnConfigurationOptions.getTaskLogger().info(
 290  3
                         "Generating report for " + ConfigurationOptions.getProjectName() + " into " + ConfigurationOptions.getOutputDir());
 291  1
                 SvnConfigurationOptions.getTaskLogger().info("Using " + ConfigurationOptions.getCssHandler());
 292  4
                 final Repository content = builder.createRepository();
 293  3
 
 294  3
                 // make JFreeChart work on systems without GUI
 295  1
                 System.setProperty("java.awt.headless", "true");
 296  3
 
 297  1
                 final ReportConfig config = new ReportConfig(content, ConfigurationOptions.getProjectName(), ConfigurationOptions.getOutputDir(), ConfigurationOptions
 298  3
                         .getMarkupSyntax(), ConfigurationOptions.getCssHandler(), ConfigurationOptions.getCharSet());
 299  1
                 config.setWebRepository(ConfigurationOptions.getWebRepository());
 300  1
                 config.setWebBugtracker(ConfigurationOptions.getWebBugtracker());
 301  1
                 config.setNonDeveloperLogins(ConfigurationOptions.getNonDeveloperLogins());
 302  3
 
 303  1
                 validate(config);
 304  3
 
 305  1
                 if (SvnConfigurationOptions.isDumpContent()) {
 306  0
                         new RepoDump(content).dump();
 307  
                 } else {
 308  0
                         // add new reports
 309  4
                         final List extraReports = new ArrayList();
 310  0
 
 311  1
                         if ("xml".equalsIgnoreCase(ConfigurationOptions.getOutputFormat())) {
 312  1
                                 new ReportSuiteMaker(config, ConfigurationOptions.getNotes(), extraReports).toXml();
 313  1
                         } else {
 314  
                                 //                                extraReports.add(new RepoMapPageMaker(config).toFile());
 315  1
                                 //                                extraReports.add(new ChurnPageMaker(config).toFile());
 316  2
                                 new ReportSuiteMaker(config, ConfigurationOptions.getNotes(), extraReports).toFile().write();
 317  1
                         }
 318  0
                 }
 319  1
                 final long endTime = System.currentTimeMillis();
 320  4
                 final long memoryUsedOnEnd = Runtime.getRuntime().totalMemory();
 321  0
 
 322  1
                 SvnConfigurationOptions.getTaskLogger().info("runtime: " + (((double) endTime - startTime) / NUMBER_OF_MS_IN_ONE_SEC) + " seconds");
 323  1
                 SvnConfigurationOptions.getTaskLogger().info("memory usage: " + (((double) memoryUsedOnEnd - memoryUsedOnStart) / KB_IN_ONE_MB) + " kb");
 324  4
         }
 325  
 
 326  0
         private static void validate(final ReportConfig config) {
 327  1
                 if (config.getRepository() == null || config.getRepository().getRoot() == null || config.getRepository().getDirectories() == null) {
 328  0
                         printErrorMessageAndExit("The repository object is not valid. Please check your settings." + System.getProperty("line.separator")
 329  
                                 + "Is the log file empty? Do you run from a checked out directory? Do you have non-committed items?");
 330  0
                 }
 331  1
         }
 332  
 }