View Javadoc

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: 2009/08/05 16:32:10 $
22  */
23  package net.sf.statcvs;
24  
25  import java.io.FileReader;
26  import java.io.IOException;
27  import java.io.Reader;
28  import java.util.ArrayList;
29  import java.util.List;
30  import java.util.logging.LogManager;
31  import java.util.logging.Logger;
32  
33  import net.sf.statcvs.input.Builder;
34  import net.sf.statcvs.input.CvsLogfileParser;
35  import net.sf.statcvs.input.LogSyntaxException;
36  import net.sf.statcvs.input.RepositoryFileManager;
37  import net.sf.statcvs.model.Repository;
38  import net.sf.statcvs.output.CommandLineParser;
39  import net.sf.statcvs.output.ConfigurationException;
40  import net.sf.statcvs.output.ConfigurationOptions;
41  import net.sf.statcvs.output.ReportConfig;
42  import net.sf.statcvs.pages.Page;
43  import net.sf.statcvs.pages.ReportSuiteMaker;
44  
45  /**
46   * StatCvs Main Class; it starts the application and controls command-line
47   * related stuff
48   * @author Lukasz Pekacki
49   * @author Richard Cyganiak
50   * @version $Id: Main.java,v 1.68 2009/08/05 16:32:10 benoitx Exp $
51   */
52  public class Main {
53      private static Logger logger = Logger.getLogger("net.sf.statcvs");
54      private static LogManager lm = LogManager.getLogManager();
55  
56      /**
57       * Main method of StatCvs
58       * @param args command line options
59       */
60      public static void main(final String[] args) {
61          System.out.println(Messages.getString("PROJECT_NAME") + Messages.NL);
62  
63          if (args.length == 0) {
64              printProperUsageAndExit();
65          }
66          if (args.length == 1) {
67              final String arg = args[0].toLowerCase();
68              if (arg.equals("-h") || arg.equals("-help")) {
69                  printProperUsageAndExit();
70              } else if (arg.equals("-version")) {
71                  printVersionAndExit();
72              }
73          }
74  
75          try {
76              new CommandLineParser(args).parse();
77              generateDefaultHTMLSuite();
78          } catch (final ConfigurationException cex) {
79              System.err.println(cex.getMessage());
80              System.exit(1);
81          } catch (final LogSyntaxException lex) {
82              printLogErrorMessageAndExit(lex.getMessage());
83          } catch (final IOException ioex) {
84              printIoErrorMessageAndExit(ioex.getMessage());
85          } catch (final OutOfMemoryError oome) {
86              printOutOfMemMessageAndExit();
87          }
88          System.exit(0);
89      }
90  
91      private static void initLogManager(final String loggingProperties) {
92          try {
93              lm.readConfiguration(Main.class.getResourceAsStream(loggingProperties));
94          } catch (final IOException e) {
95              System.err.println("ERROR: Logging could not be initialized!");
96          }
97      }
98  
99      private static void printProperUsageAndExit() {
100         System.out.println(
101         //max. 80 chars
102                 //         12345678901234567890123456789012345678901234567890123456789012345678901234567890
103                 "Usage: java -jar statcvs.jar [options] <logfile> <directory>\n" + "\n" + "Required parameters:\n"
104                         + "  <logfile>          path to the cvs logfile of the module\n"
105                         + "  <directory>        path to the directory of the checked out module\n" + "\n" + "Some options:\n"
106                         + "  -version           print version information and exit\n" + "  -output-dir <dir>  set directory where HTML suite will be saved\n"
107                         + "  -include <pattern> include only files matching pattern, e.g. **/*.c;**/*.h\n"
108                         + "  -exclude <pattern> exclude matching files, e.g. tests/**;docs/**\n"
109                         + "  -tags <regexp>     show matching tags in lines of code chart, e.g. version-.*\n"
110                         + "  -title <title>     set project title to be used in reports\n" + "  -xdoc              generate Maven XDoc instead of HTML\n"
111                         + "  -trac <url>        integrate with Trac at <url>\n" + "  -xml               generate XML instead of HTML\n"
112                         + "  -charset <charset> specify the charset to use for html/xdoc\n" + "  -verbose           print extra progress information\n"
113                         + "  -viewcvs/viewvc/cvsweb/chora/jcvsweb/bugzilla/mantis <url>\n" + "                     add links to installation at <url>\n"
114                         + "  -disable-twitter-button\n" + "\n" + "Full options list: http://statcvs.sf.net/manual");
115         System.exit(1);
116     }
117 
118     private static void printVersionAndExit() {
119         System.out.println("Version " + Messages.getString("PROJECT_VERSION"));
120         System.exit(1);
121     }
122 
123     private static void printOutOfMemMessageAndExit() {
124         System.err.println("OutOfMemoryError.");
125         System.err.println("Try running java with the -mx option (e.g. -mx128m for 128Mb).");
126         System.exit(1);
127     }
128 
129     private static void printLogErrorMessageAndExit(final String message) {
130         System.err.println("Logfile parsing failed.");
131         System.err.println(message);
132         System.exit(1);
133     }
134 
135     private static void printIoErrorMessageAndExit(final String message) {
136         System.err.println(message);
137         System.exit(1);
138     }
139 
140     /**
141      * Generates HTML report. {@link net.sf.statcvs.output.ConfigurationOptions}
142      * must be initialized before calling this method.
143      * @throws LogSyntaxException if the logfile contains unexpected syntax
144      * @throws IOException if some file can't be read or written
145      * @throws ConfigurationException if a required ConfigurationOption was not set
146      */
147     public static void generateDefaultHTMLSuite() throws LogSyntaxException, IOException, ConfigurationException {
148 
149         if (ConfigurationOptions.getLogFileName() == null) {
150             throw new ConfigurationException("Missing logfile name");
151         }
152         if (ConfigurationOptions.getCheckedOutDirectory() == null) {
153             throw new ConfigurationException("Missing checked out directory");
154         }
155 
156         final long memoryUsedOnStart = Runtime.getRuntime().totalMemory();
157         final long startTime = System.currentTimeMillis();
158 
159         initLogManager(ConfigurationOptions.getLoggingProperties());
160 
161         logger.info("Parsing CVS log '" + ConfigurationOptions.getLogFileName() + "'");
162 
163         Reader logReader = null;
164         Builder builder = null;
165         try {
166             logReader = new FileReader(ConfigurationOptions.getLogFileName());
167             final RepositoryFileManager repFileMan = new RepositoryFileManager(ConfigurationOptions.getCheckedOutDirectory());
168 
169             builder = new Builder(repFileMan, ConfigurationOptions.getIncludePattern(), ConfigurationOptions.getExcludePattern(), ConfigurationOptions
170                     .getSymbolicNamesPattern());
171             new CvsLogfileParser(logReader, builder).parse();
172         } finally {
173             if (logReader != null) {
174                 logReader.close();
175             }
176         }
177         if (ConfigurationOptions.getProjectName() == null) {
178             ConfigurationOptions.setProjectName(builder.getProjectName());
179         }
180         if (ConfigurationOptions.getWebRepository() != null) {
181             ConfigurationOptions.getWebRepository().setAtticFileNames(builder.getAtticFileNames());
182         }
183         logger.info("Generating report for " + ConfigurationOptions.getProjectName() + " into " + ConfigurationOptions.getOutputDir());
184         logger.info("Using " + ConfigurationOptions.getCssHandler());
185         final Repository content = builder.createCvsContent();
186         if (content.isEmpty()) {
187             if (builder.allRejectedByExcludePattern()) {
188                 logger.warning("Exclude pattern '" + ConfigurationOptions.getExcludePattern() + "' removed all files from repository");
189             } else if (builder.allRejectedByIncludePattern()) {
190                 logger.warning("Include pattern '" + ConfigurationOptions.getIncludePattern() + "' rejected all files from repository");
191             } else {
192                 logger.warning("Empty repository");
193             }
194         }
195         if (builder.isLocalFilesNotFound()) {
196             logger.warning("The log references many files that do not exist in the local copy.");
197             logger.warning("Reports will be inaccurate or broken.");
198             logger.warning("Log not generated in '" + ConfigurationOptions.getCheckedOutDirectory() + "'?");
199         } else if (!builder.hasLocalCVSMetadata()) {
200             logger.warning("No CVS metadata found in working copy. Reports may be inaccurate.");
201         } else if (builder.isLogAndLocalFilesOutOfSync()) {
202             logger.warning("Log and working copy are out of sync. Reports will be inaccurate.");
203         }
204 
205         builder.clean();
206         builder = null;
207         
208         // make JFreeChart work on systems without GUI
209         System.setProperty("java.awt.headless", "true");
210 
211         final ReportConfig config = new ReportConfig(content, ConfigurationOptions.getProjectName(), ConfigurationOptions.getOutputDir(), ConfigurationOptions
212                 .getMarkupSyntax(), ConfigurationOptions.getCssHandler(), ConfigurationOptions.getCharSet());
213         config.setWebRepository(ConfigurationOptions.getWebRepository());
214         config.setWebBugtracker(ConfigurationOptions.getWebBugtracker());
215         config.setNonDeveloperLogins(ConfigurationOptions.getNonDeveloperLogins());
216 
217         final List extraReports = new ArrayList();
218         //        extraReports.add(new RepoMapPageMaker(config).toFile());
219         //        extraReports.add(new ChurnPageMaker(config).toFile());
220 
221         ReportSuiteMaker reportSuiteMaker = new ReportSuiteMaker(config, ConfigurationOptions.getNotes(), extraReports);
222         if ("xml".equalsIgnoreCase(ConfigurationOptions.getOutputFormat())) {
223             reportSuiteMaker.toXml();
224         } else {
225             Page page = reportSuiteMaker.toFile();
226             
227 //            logger.info("*********** Do A DUMP NOW ************");
228 //            try {
229 //                Thread.sleep(20000);
230 //            } catch (InterruptedException e) {
231 //                // TODO Auto-generated catch block
232 //                e.printStackTrace();
233 //            }
234             
235             
236             page.write();
237 
238 //            logger.info("*********** Do A SECOND DUMP NOW ************");
239 //            try {
240 //                Thread.sleep(20000);
241 //            } catch (InterruptedException e) {
242 //                // TODO Auto-generated catch block
243 //                e.printStackTrace();
244 //            }
245 }
246 
247         final long endTime = System.currentTimeMillis();
248         final long memoryUsedOnEnd = Runtime.getRuntime().totalMemory();
249 
250         logger.info("runtime: " + (((double) endTime - startTime) / 1000) + " seconds");
251         logger.info("memory usage: " + (((double) memoryUsedOnEnd - memoryUsedOnStart) / 1024) + " kb");
252     }
253 }