package com.softsizo.ui;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Properties;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import com.softsizo.data.ConfigParameters;
import com.softsizo.data.ExtractedData;
import com.softsizo.explorer.RepositoryExplorer;
import com.softsizo.explorer.RepositoryExplorerException;
import com.softsizo.report.ReportBuilder;
import com.softsizo.report.ReportException;
/**
* Console based front end for SoftSizo.
* Its main method initialises a ConfigParameters instance with argument values,
* extracts data from the SVN repository, and generates the report.
*
* @author Sergio Fierens
*/
public class ConsoleFrontEnd {
public static final String APP_NAME = "softsizo";
private ConfigParameters configParameters;
private ExtractedData data;
private ReportBuilder reportBuilder;
private RepositoryExplorer repositoryExplorer;
private PrintStream printStream;
static Logger logger = Logger.getLogger(ConsoleFrontEnd.class);
/**
* Console application entry point.
* @param args
*/
public static void main(String[] args) {
XmlBeanFactory bf =
new XmlBeanFactory(
new ClassPathResource("application-context.xml"));
ConsoleFrontEnd frontEnd =
(ConsoleFrontEnd) bf.getBean("consoleFrontEnd");
frontEnd.run(args);
}
/**
* This method initialises a ConfigParameters instance with argument values,
* extracts data from the SVN repository, and generates the report.
*
* @param args
* @throws Exception
*/
public void run(String [] args){
Options options = buildOptions();
try {
long start = System.currentTimeMillis();
if(this.parseParameters(options, args)) {
logger.info("Report generation started at " + new Date());
this.exploreRepository();
this.generateReport();
logger.info("Report generation finished at " + new Date());
logger.info("Elapsed minutes since start: " +
((System.currentTimeMillis()-start)/(60*1000F)));
}
} catch(Exception e) {
logger.error("There has been an error a fatal error: " + e.getMessage());
}
}
public void setPrintStream(PrintStream printStream){
this.printStream = printStream;
}
public void setReportBuilder(ReportBuilder reportBuilder) {
this.reportBuilder = reportBuilder;
}
public void setRepositoryExplorer(RepositoryExplorer repositoryExplorer) {
this.repositoryExplorer = repositoryExplorer;
}
private void generateReport() throws ReportException {
reportBuilder.generateReport(this.data, this.configParameters.getOutputDirectory());
}
protected void exploreRepository() throws RepositoryExplorerException {
this.data = this.repositoryExplorer.explore(configParameters);
}
protected boolean parseParameters(Options options, String[] args) throws Exception {
CommandLineParser parser = new GnuParser();
try {
CommandLine commandLine = parser.parse( options, args );
configParameters = buildConfigParameters(commandLine, options);
validateConfigParameters();
}
catch( ParseException exp ) {
logger.error( "Invalid arguments. " + exp.getMessage() );
} catch (ConfigParametersException e) {
logger.error(e.getMessage());
printHelp(options);
}
return configParameters != null;
}
protected void validateConfigParameters() throws ConfigParametersException {
if(configParameters!=null) {
if(configParameters.getFromRevision() <= 0){
throw new ConfigParametersException("Initial revision must be greater than or equal to 1");
}else if((configParameters.getFromRevision() >= configParameters.getToRevision())
&& (configParameters.getToRevision() != ConfigParameters.HEAD_REVISION)){
throw new ConfigParametersException("Final revision must be greater than initial revision");
}else if(configParameters.getRepoUrl()==null) {
throw new ConfigParametersException("You must specify repository url");
}
}
}
protected ConfigParameters buildConfigParameters(CommandLine cmd, Options options) throws Exception {
if(cmd.hasOption("h")){
printHelp(options);
return null;
}else if(cmd.hasOption("v")){
printVersion();
return null;
}
ConfigParameters config = new ConfigParameters();
if(cmd.hasOption("f")){
config.setFromRevision(new Integer(options.getOption("f").getValue()));
}
if(cmd.hasOption("t")){
config.setToRevision(new Integer(options.getOption("t").getValue()));
}
if(cmd.hasOption("u")){
config.setUsername(options.getOption("u").getValue());
}
if(cmd.hasOption("p")){
config.setPassword(options.getOption("p").getValue());
}
if(cmd.hasOption("o")){
config.setOutputDirectory(options.getOption("o").getValue());
}
if(cmd.hasOption("e")){
config.setExclude(options.getOption("e").getValue());
}
if(cmd.hasOption("i")){
config.setInclude(options.getOption("i").getValue());
}
config.setRepoUrl(options.getOption("r").getValue());
return config;
}
protected void printVersion() throws Exception {
InputStream is = this.getClass().getResourceAsStream("/version.properties");
if(is==null){
throw new Exception("Version properties file could not be found");
}
Properties properties = new Properties();
properties.load(is);
String version = properties.getProperty("version");
printStream.println(APP_NAME + " v" + version);
}
protected void printHelp(Options options) {
HelpFormatter formatter = new HelpFormatter();
PrintWriter writer = new PrintWriter(printStream);
formatter.printHelp(writer, 800, APP_NAME,
"", options, 0, 0, "");
writer.flush();
writer.close();
}
@SuppressWarnings("static-access")
protected static Options buildOptions(){
Options options = new Options();
options.addOption( "h", "help", false, "print this message" );
options.addOption( "v", "version", false, "print version of this application" );
options.addOption( OptionBuilder.withArgName("f")
.withLongOpt( "fromRevision" )
.withDescription( "Number of the first revision for the report" )
.hasArg()
.create("f") );
options.addOption( OptionBuilder.withArgName("t")
.withLongOpt( "toRevision" )
.withDescription( "Number of the last revision included in the report" )
.hasArg()
.create("t") );
options.addOption( OptionBuilder.withArgName("r")
.withLongOpt( "repository" )
.withDescription( "SVN repository url" )
.hasArg()
.create("r") );
options.addOption( OptionBuilder.withArgName("o")
.withLongOpt( "output" )
.withDescription( "Output directory" )
.hasArg()
.create("o") );
options.addOption( OptionBuilder.withArgName("u")
.withLongOpt( "user" )
.withDescription( "SVN username" )
.hasArg()
.create("u") );
options.addOption( OptionBuilder.withArgName("p")
.withLongOpt( "password" )
.withDescription( "SVN user password" )
.hasArg()
.create("p") );
options.addOption( OptionBuilder.withArgName("i")
.withLongOpt( "include" )
.withDescription( "Include filter (regular expression)" )
.hasArg()
.create("i") );
options.addOption( OptionBuilder.withArgName("e")
.withLongOpt( "exclude" )
.withDescription( "Exclude filter (regular expression)" )
.hasArg()
.create("e") );
return options;
}
}